- Complete revamp of isolate-specific flags.
- Associate flags with the isolate on creation.
- Dart_CreateIsolate and associate callback do take an
  extra flags argument.
- Make sure to clear IC data array when clearing code.

BUG=23578

Review URL: https://codereview.chromium.org//1162033005
This commit is contained in:
Ivan Posva 2015-06-07 17:57:34 +02:00
parent deb1697fa9
commit f5e3f94019
45 changed files with 388 additions and 226 deletions

View file

@ -554,7 +554,8 @@ int main(int argc, char** argv) {
}
char* error;
Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error);
Dart_Isolate isolate = Dart_CreateIsolate(
NULL, NULL, NULL, NULL, NULL, &error);
if (isolate == NULL) {
Log::PrintErr("Error: %s", error);
free(error);
@ -600,7 +601,7 @@ int main(int argc, char** argv) {
// Now we create an isolate into which we load all the code that needs to
// be in the snapshot.
if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, NULL, &error) == NULL) {
fprintf(stderr, "%s", error);
free(error);
exit(255);

View file

@ -579,6 +579,7 @@ static Dart_Handle EnvironmentCallback(Dart_Handle name) {
static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
const char* main,
const char* package_root,
Dart_IsolateFlags* flags,
char** error,
int* exit_code) {
ASSERT(script_uri != NULL);
@ -588,6 +589,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
isolate = Dart_CreateIsolate(script_uri,
main,
isolate_snapshot_buffer,
flags,
isolate_data,
error);
@ -673,7 +675,11 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
const char* main,
const char* package_root,
Dart_IsolateFlags* flags,
void* data, char** error) {
// The VM should never call the isolate helper with a NULL flags.
ASSERT(flags != NULL);
ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
IsolateData* parent_isolate_data = reinterpret_cast<IsolateData*>(data);
int exit_code = 0;
if (script_uri == NULL) {
@ -697,6 +703,7 @@ static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
return CreateIsolateAndSetupHelper(script_uri,
main,
package_root,
flags,
error,
&exit_code);
}
@ -967,6 +974,7 @@ void main(int argc, char** argv) {
Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
"main",
commandline_package_root,
NULL,
&error,
&exit_code);
if (isolate == NULL) {

View file

@ -45,6 +45,7 @@ Dart_Isolate VmServiceServer::CreateIsolate(const uint8_t* snapshot_buffer) {
"main",
snapshot_buffer,
NULL,
NULL,
&error);
if (!isolate) {
fprintf(stderr, "Dart_CreateIsolate failed: %s\n", error);

View file

@ -685,6 +685,23 @@ DART_EXPORT Dart_Handle Dart_VisitPrologueWeakHandles(
*/
DART_EXPORT const char* Dart_VersionString();
/**
* Isolate specific flags are set when creating a new isolate using the
* Dart_IsolateFlags structure.
*
* Current version of flags is encoded in a 32-bit integer with 16 bits used
* for each part.
*/
#define DART_FLAGS_CURRENT_VERSION (0x00000001)
typedef struct {
int32_t version;
bool enable_type_checks;
bool enable_asserts;
} Dart_IsolateFlags;
/**
* An isolate creation and initialization callback function.
*
@ -723,6 +740,9 @@ DART_EXPORT const char* Dart_VersionString();
* \param package_root The package root path for this isolate to resolve
* package imports against. If this parameter is NULL, the package root path
* of the parent isolate should be used.
* \param flags Default flags for this isolate being spawned. Either inherited
* from the spawning isolate or passed as parameters when spawning the
* isolate from Dart code.
* \param callback_data The callback data which was passed to the
* parent isolate when it was created by calling Dart_CreateIsolate().
* \param error A structure into which the embedder can place a
@ -734,6 +754,7 @@ DART_EXPORT const char* Dart_VersionString();
typedef Dart_Isolate (*Dart_IsolateCreateCallback)(const char* script_uri,
const char* main,
const char* package_root,
Dart_IsolateFlags* flags,
void* callback_data,
char** error);
@ -894,6 +915,7 @@ DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name);
* Provided only for advisory purposes to improve debugging messages.
* \param snapshot A buffer containing a snapshot of the isolate or
* NULL if no snapshot is provided.
* \param flags Pointer to VM specific flags or NULL for default flags.
* \param callback_data Embedder data. This data will be passed to
* the Dart_IsolateCreateCallback when new isolates are spawned from
* this parent isolate.
@ -905,6 +927,7 @@ DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name);
DART_EXPORT Dart_Isolate Dart_CreateIsolate(const char* script_uri,
const char* main,
const uint8_t* snapshot,
Dart_IsolateFlags* flags,
void* callback_data,
char** error);
/* TODO(turnidge): Document behavior when there is already a current

View file

@ -171,21 +171,20 @@ static bool CreateIsolate(Isolate* parent_isolate,
return false;
}
Dart_IsolateFlags api_flags;
state->isolate_flags()->CopyTo(&api_flags);
void* init_data = parent_isolate->init_callback_data();
Isolate* child_isolate = reinterpret_cast<Isolate*>(
(callback)(state->script_url(),
state->function_name(),
state->package_root(),
&api_flags,
init_data,
error));
if (child_isolate == NULL) {
return false;
}
// TODO(iposva): Evaluate whether it's ok to override the embedder's setup.
// Currently the strict_compilation flag is ignored if it's false and
// checked-mode was enabled using a command-line flag. The command-line flag
// overrides the user code's request.
child_isolate->set_strict_compilation(state->checked_mode());
if (!state->is_spawn_uri()) {
// For isolates spawned using the spawn semantics we set
// the origin_id to the origin_id of the parent isolate.
@ -234,12 +233,10 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 4) {
#endif
// Get the parent function so that we get the right function name.
func = func.parent_function();
bool checkedFlag = isolate->strict_compilation();
Spawn(isolate, new IsolateSpawnState(port.Id(),
func,
message,
paused.value(),
checkedFlag));
paused.value()));
return Object::null();
}
}
@ -278,20 +275,19 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 7) {
utf8_package_root[len] = '\0';
}
bool checkedFlag;
if (checked.IsNull()) {
checkedFlag = isolate->strict_compilation();
} else {
checkedFlag = checked.value();
IsolateSpawnState* state = new IsolateSpawnState(port.Id(),
canonical_uri,
utf8_package_root,
args,
message,
paused.value());
// If we were passed a value then override the default flags state for
// checked mode.
if (!checked.IsNull()) {
state->isolate_flags()->set_checked(checked.value());
}
Spawn(isolate, new IsolateSpawnState(port.Id(),
canonical_uri,
utf8_package_root,
args,
message,
paused.value(),
checkedFlag));
Spawn(isolate, state);
return Object::null();
}

View file

@ -271,7 +271,7 @@ DEFINE_NATIVE_ENTRY(Object_as, 4) {
location, instance_type_name, type_name,
dst_name, Object::null_string());
} else {
ASSERT(Isolate::Current()->TypeChecksEnabled());
ASSERT(isolate->flags().type_checks());
bound_error_message = String::New(bound_error.ToErrorCString());
Exceptions::CreateAndThrowTypeError(
location, instance_type_name, Symbols::Empty(),

View file

@ -517,7 +517,7 @@ AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) {
if (field().is_final()) {
return NULL;
}
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
rhs = new AssignableNode(
field().token_pos(),
rhs,
@ -557,11 +557,14 @@ AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) {
AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
if (is_super_getter()) {
ASSERT(receiver() != NULL);
const String& setter_name =
String::ZoneHandle(Field::SetterSymbol(field_name_));
Function& setter = Function::ZoneHandle(
String::ZoneHandle(zone, Field::SetterSymbol(field_name_));
Function& setter = Function::ZoneHandle(zone,
Resolver::ResolveDynamicAnyArgs(cls(), setter_name));
if (setter.IsNull() || setter.is_abstract()) {
// No instance setter found in super class chain,
@ -591,14 +594,14 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
Object& obj = Object::Handle(prefix.LookupObject(field_name_));
Object& obj = Object::Handle(zone, prefix.LookupObject(field_name_));
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(Field::Cast(obj).raw());
const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
if (!field.is_final()) {
if (Isolate::Current()->TypeChecksEnabled()) {
if (isolate->flags().type_checks()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(field.type()),
AbstractType::ZoneHandle(zone, field.type()),
field_name_);
}
return new StoreStaticFieldNode(token_pos(), field, rhs);
@ -606,10 +609,12 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
}
// No field found in prefix. Look for a setter function.
const String& setter_name = String::Handle(Field::SetterName(field_name_));
const String& setter_name = String::Handle(zone,
Field::SetterName(field_name_));
obj = prefix.LookupObject(setter_name);
if (obj.IsFunction()) {
const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw());
const Function& setter = Function::ZoneHandle(zone,
Function::Cast(obj).raw());
ASSERT(setter.is_static() && setter.IsSetterFunction());
return new StaticSetterNode(
token_pos(), NULL, field_name_, setter, rhs);
@ -622,14 +627,14 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
if (owner().IsLibrary()) {
const Library& library = Library::Cast(owner());
Object& obj = Object::Handle(library.ResolveName(field_name_));
Object& obj = Object::Handle(zone, library.ResolveName(field_name_));
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(Field::Cast(obj).raw());
const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
if (!field.is_final()) {
if (Isolate::Current()->TypeChecksEnabled()) {
if (isolate->flags().type_checks()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(field.type()),
AbstractType::ZoneHandle(zone, field.type()),
field_name_);
}
return new StoreStaticFieldNode(token_pos(), field, rhs);
@ -637,10 +642,12 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
}
// No field found in library. Look for a setter function.
const String& setter_name = String::Handle(Field::SetterName(field_name_));
const String& setter_name = String::Handle(zone,
Field::SetterName(field_name_));
obj = library.ResolveName(setter_name);
if (obj.IsFunction()) {
const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw());
const Function& setter = Function::ZoneHandle(zone,
Function::Cast(obj).raw());
ASSERT(setter.is_static() && setter.IsSetterFunction());
return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
}
@ -651,7 +658,7 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
}
const Function& setter =
Function::ZoneHandle(cls().LookupSetterFunction(field_name_));
Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_));
if (!setter.IsNull() && setter.IsStaticFunction()) {
return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
}
@ -659,7 +666,8 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
// Access to a lazily initialized static field that has not yet been
// initialized is compiled to a static implicit getter.
// A setter may not exist for such a field.
const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name_));
const Field& field = Field::ZoneHandle(zone,
cls().LookupStaticField(field_name_));
if (!field.IsNull()) {
if (field.is_final()) {
// Attempting to assign to a final variable will cause a NoSuchMethodError
@ -668,18 +676,19 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
#if defined(DEBUG)
const String& getter_name = String::Handle(Field::GetterName(field_name_));
const String& getter_name = String::Handle(zone,
Field::GetterName(field_name_));
const Function& getter =
Function::Handle(cls().LookupStaticFunction(getter_name));
Function::Handle(zone, cls().LookupStaticFunction(getter_name));
ASSERT(!getter.IsNull() &&
(getter.kind() == RawFunction::kImplicitStaticFinalGetter));
#endif
if (Isolate::Current()->TypeChecksEnabled()) {
if (isolate->flags().type_checks()) {
rhs = new AssignableNode(
field.token_pos(),
rhs,
AbstractType::ZoneHandle(field.type()),
String::ZoneHandle(field.name()));
AbstractType::ZoneHandle(zone, field.type()),
String::ZoneHandle(zone, field.name()));
}
return new StoreStaticFieldNode(token_pos(), field, rhs);
}

View file

@ -81,7 +81,7 @@ class Benchmark {
Dart_Isolate CreateIsolate(const uint8_t* buffer) {
char* err = NULL;
isolate_ = Dart_CreateIsolate(NULL, NULL, buffer, NULL, &err);
isolate_ = Dart_CreateIsolate(NULL, NULL, buffer, NULL, NULL, &err);
EXPECT(isolate_ != NULL);
free(err);
return isolate_;

View file

@ -15,10 +15,6 @@
namespace dart {
DEFINE_FLAG(bool, error_on_bad_override, false,
"Report error for bad overrides.");
DEFINE_FLAG(bool, error_on_bad_type, false,
"Report error for malformed types.");
DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
@ -377,7 +373,7 @@ void ClassFinalizer::ResolveRedirectingFactoryTarget(
return;
}
if (Isolate::Current()->ErrorOnBadOverrideEnabled()) {
if (Isolate::Current()->flags().error_on_bad_override()) {
// Verify that the target is compatible with the redirecting factory.
Error& error = Error::Handle();
if (!target.HasCompatibleParametersWith(factory, &error)) {
@ -1000,7 +996,7 @@ RawAbstractType* ClassFinalizer::FinalizeType(
TypeArguments::Handle(isolate, parameterized_type.arguments());
if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
// Wrong number of type arguments. The type is mapped to the raw type.
if (Isolate::Current()->ErrorOnBadTypeEnabled()) {
if (Isolate::Current()->flags().error_on_bad_type()) {
const String& type_class_name =
String::Handle(isolate, type_class.Name());
ReportError(cls, parameterized_type.token_pos(),
@ -1371,7 +1367,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
!const_value.IsInstanceOf(type,
Object::null_type_arguments(),
&error))) {
if (Isolate::Current()->ErrorOnBadTypeEnabled()) {
if (Isolate::Current()->flags().error_on_bad_type()) {
const AbstractType& const_value_type = AbstractType::Handle(
I, const_value.GetType());
const String& const_value_type_name = String::Handle(
@ -1435,7 +1431,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
ResolveAndFinalizeSignature(cls, function);
name = function.name();
// Report signature conflicts only.
if (Isolate::Current()->ErrorOnBadOverrideEnabled() &&
if (Isolate::Current()->flags().error_on_bad_override() &&
!function.is_static() && !function.IsGenerativeConstructor()) {
// A constructor cannot override anything.
for (intptr_t i = 0; i < interfaces.Length(); i++) {
@ -2595,7 +2591,7 @@ void ClassFinalizer::CollectTypeArguments(
}
return;
}
if (Isolate::Current()->ErrorOnBadTypeEnabled()) {
if (Isolate::Current()->flags().error_on_bad_type()) {
const String& type_class_name = String::Handle(type_class.Name());
ReportError(cls, type.token_pos(),
"wrong number of type arguments for class '%s'",
@ -3018,7 +3014,7 @@ void ClassFinalizer::MarkTypeMalformed(const Error& prev_error,
prev_error, script, type.token_pos(),
Report::kMalformedType, Heap::kOld,
format, args));
if (Isolate::Current()->ErrorOnBadTypeEnabled()) {
if (Isolate::Current()->flags().error_on_bad_type()) {
ReportError(error);
}
type.set_error(error);
@ -3080,7 +3076,7 @@ void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error,
Report::kMalboundedType, Heap::kOld,
format, args));
va_end(args);
if (Isolate::Current()->ErrorOnBadTypeEnabled()) {
if (Isolate::Current()->flags().error_on_bad_type()) {
ReportError(error);
}
type.set_error(error);

View file

@ -225,7 +225,7 @@ DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) {
// Code inlined in the caller should have optimized the case where the
// instantiator can be reused as type argument vector.
ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
if (Isolate::Current()->TypeChecksEnabled()) {
if (isolate->flags().type_checks()) {
Error& bound_error = Error::Handle();
type_arguments =
type_arguments.InstantiateAndCanonicalizeFrom(instantiator,
@ -530,7 +530,7 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
}
String& bound_error_message = String::Handle();
if (!bound_error.IsNull()) {
ASSERT(Isolate::Current()->TypeChecksEnabled());
ASSERT(isolate->flags().type_checks());
bound_error_message = String::New(bound_error.ToErrorCString());
}
if (src_type_name.Equals(dst_type_name)) {

View file

@ -790,6 +790,9 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
}
}
}
// Mark that this isolate now has compiled code.
isolate->set_has_compiled(true);
// Exit the loop and the function with the correct result value.
is_compiled = true;
done = true;
} else {
@ -1191,6 +1194,7 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) {
if (!error.IsNull()) {
return error.raw();
}
func.ClearICDataArray();
func.ClearCode();
}
}
@ -1207,6 +1211,7 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) {
if (!error.IsNull()) {
return error.raw();
}
func.ClearICDataArray();
func.ClearCode();
}
}

View file

@ -13,8 +13,6 @@
namespace dart {
DECLARE_FLAG(bool, enable_type_checks);
TEST_CASE(CompileScript) {
const char* kScriptChars =
"class A {\n"
@ -81,8 +79,7 @@ TEST_CASE(RegenerateAllocStubs) {
" return unOpt();\n"
"}\n";
bool old_enable_type_checks = FLAG_enable_type_checks;
FLAG_enable_type_checks = true;
// Isolate::Current()->flags().set_checked(true);
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
EXPECT_VALID(result);
@ -109,8 +106,6 @@ TEST_CASE(RegenerateAllocStubs) {
owner.DisableAllocationStub();
result = Dart_Invoke(lib, NewString("main"), 0, NULL);
EXPECT_VALID(result);
FLAG_enable_type_checks = old_enable_type_checks;
}

View file

@ -118,7 +118,13 @@ const char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot,
ASSERT(Flags::Initialized());
const bool is_vm_isolate = true;
Thread::EnsureInit();
vm_isolate_ = Isolate::Init("vm-isolate", is_vm_isolate);
// Setup default flags for the VM isolate.
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate);
StackZone zone(vm_isolate_);
HandleScope handle_scope(vm_isolate_);
Heap::Init(vm_isolate_,
@ -226,9 +232,10 @@ const char* Dart::Cleanup() {
}
Isolate* Dart::CreateIsolate(const char* name_prefix) {
Isolate* Dart::CreateIsolate(const char* name_prefix,
const Dart_IsolateFlags& api_flags) {
// Create a new isolate.
Isolate* isolate = Isolate::Init(name_prefix);
Isolate* isolate = Isolate::Init(name_prefix, api_flags);
ASSERT(isolate != NULL);
return isolate;
}

View file

@ -32,7 +32,8 @@ class Dart : public AllStatic {
Dart_EntropySource entropy_source);
static const char* Cleanup();
static Isolate* CreateIsolate(const char* name_prefix);
static Isolate* CreateIsolate(const char* name_prefix,
const Dart_IsolateFlags& api_flags);
static RawError* InitializeIsolate(const uint8_t* snapshot, void* data);
static void RunShutdownCallback();
static void ShutdownIsolate();

View file

@ -1287,12 +1287,21 @@ static char* BuildIsolateName(const char* script_uri,
DART_EXPORT Dart_Isolate Dart_CreateIsolate(const char* script_uri,
const char* main,
const uint8_t* snapshot,
Dart_IsolateFlags* flags,
void* callback_data,
char** error) {
CHECK_NO_ISOLATE(Isolate::Current());
char* isolate_name = BuildIsolateName(script_uri, main);
Thread::EnsureInit();
Isolate* isolate = Dart::CreateIsolate(isolate_name);
// Setup default flags in case none were passed.
Dart_IsolateFlags api_flags;
if (flags == NULL) {
Isolate::Flags vm_flags;
vm_flags.CopyTo(&api_flags);
flags = &api_flags;
}
Isolate* isolate = Dart::CreateIsolate(isolate_name, *flags);
free(isolate_name);
StackZone zone(isolate);
HANDLESCOPE(isolate);
@ -1405,6 +1414,7 @@ DART_EXPORT void Dart_ExitIsolate() {
}
// TODO(iposva): Remove this API and instead expose the underlying flags.
DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value) {
CHECK_ISOLATE(Isolate::Current());
Isolate* isolate = Isolate::Current();
@ -1412,7 +1422,11 @@ DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value) {
return Api::NewError(
"%s expects that the isolate has not yet compiled code.", CURRENT_FUNC);
}
Isolate::Current()->set_strict_compilation(value);
if (!value) {
return Api::NewError(
"%s expects that the value is set to true only.", CURRENT_FUNC);
}
Isolate::Current()->set_strict_compilation();
return Api::Null();
}
@ -3999,8 +4013,6 @@ DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
// other operations (gc, compilation) are active.
TIMERSCOPE(isolate, time_dart_execution);
isolate->set_has_compiled(true);
const String& function_name = Api::UnwrapStringHandle(isolate, name);
if (function_name.IsNull()) {
RETURN_TYPE_ERROR(isolate, name, String);

View file

@ -3711,7 +3711,7 @@ UNIT_TEST_CASE(CurrentIsolateData) {
intptr_t mydata = 12345;
char* err;
Dart_Isolate isolate =
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer,
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL,
reinterpret_cast<void*>(mydata),
&err);
EXPECT(isolate != NULL);
@ -7311,6 +7311,7 @@ UNIT_TEST_CASE(NewNativePort) {
static Dart_Isolate RunLoopTestCallback(const char* script_name,
const char* main,
const char* package_root,
Dart_IsolateFlags* flags,
void* data,
char** error) {
const char* kScriptChars =
@ -7383,7 +7384,8 @@ static void RunLoopTest(bool throw_exception_child,
Dart_IsolateCreateCallback saved = Isolate::CreateCallback();
Isolate::SetCreateCallback(RunLoopTestCallback);
Isolate::SetUnhandledExceptionCallback(RunLoopUnhandledExceptionCallback);
Dart_Isolate isolate = RunLoopTestCallback(NULL, NULL, NULL, NULL, NULL);
Dart_Isolate isolate = RunLoopTestCallback(
NULL, NULL, NULL, NULL, NULL, NULL);
Dart_EnterIsolate(isolate);
Dart_EnterScope();
@ -7485,6 +7487,7 @@ void BusyLoop_start(uword unused) {
char* error = NULL;
shared_isolate = Dart_CreateIsolate(NULL, NULL,
bin::isolate_snapshot_buffer,
NULL,
NULL, &error);
EXPECT(shared_isolate != NULL);
Dart_EnterScope();
@ -7613,6 +7616,7 @@ UNIT_TEST_CASE(IsolateShutdown) {
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL,
bin::isolate_snapshot_buffer,
NULL,
my_data, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);
@ -7663,6 +7667,7 @@ UNIT_TEST_CASE(IsolateShutdownRunDartCode) {
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL,
bin::isolate_snapshot_buffer,
NULL,
NULL, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);

View file

@ -951,8 +951,9 @@ BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
void TestGraphVisitor::ReturnValue(Value* value) {
if (Isolate::Current()->TypeChecksEnabled() ||
Isolate::Current()->AssertsEnabled()) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() ||
isolate->flags().asserts()) {
value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
}
Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
@ -987,7 +988,7 @@ void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
false)); // No number check.
} else {
branch = new(Z) BranchInstr(comp);
branch->set_is_checked(Isolate::Current()->TypeChecksEnabled());
branch->set_is_checked(Isolate::Current()->flags().type_checks());
}
AddInstruction(branch);
CloseFragment();
@ -997,7 +998,7 @@ void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
ASSERT(!Isolate::Current()->TypeChecksEnabled());
ASSERT(!Isolate::Current()->flags().type_checks());
Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
StrictCompareInstr* comp =
new(Z) StrictCompareInstr(condition_token_pos(),
@ -1019,7 +1020,7 @@ void TestGraphVisitor::ReturnDefinition(Definition* definition) {
MergeBranchWithComparison(comp);
return;
}
if (!Isolate::Current()->TypeChecksEnabled()) {
if (!Isolate::Current()->flags().type_checks()) {
BooleanNegateInstr* neg = definition->AsBooleanNegate();
if (neg != NULL) {
MergeBranchWithNegate(neg);
@ -1111,7 +1112,7 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
return_value = Bind(BuildLoadLocal(*temp));
}
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const bool is_implicit_dynamic_getter =
(!function.is_static() &&
((function.kind() == RawFunction::kImplicitGetter) ||
@ -1311,8 +1312,9 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
TestGraphVisitor for_left(owner(), node->left()->token_pos());
node->left()->Visit(&for_left);
EffectGraphVisitor empty(owner());
if (Isolate::Current()->TypeChecksEnabled() ||
Isolate::Current()->AssertsEnabled()) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() ||
isolate->flags().asserts()) {
ValueGraphVisitor for_right(owner());
node->right()->Visit(&for_right);
Value* right_value = for_right.value();
@ -1377,8 +1379,9 @@ void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
ValueGraphVisitor for_right(owner());
node->right()->Visit(&for_right);
Value* right_value = for_right.value();
if (Isolate::Current()->TypeChecksEnabled() ||
Isolate::Current()->AssertsEnabled()) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() ||
isolate->flags().asserts()) {
right_value =
for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
right_value));
@ -1914,8 +1917,9 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
kNumArgsChecked,
owner()->ic_data_array());
if (node->kind() == Token::kNE) {
if (Isolate::Current()->TypeChecksEnabled() ||
Isolate::Current()->AssertsEnabled()) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() ||
isolate->flags().asserts()) {
Value* value = Bind(result);
result = new(Z) AssertBooleanInstr(node->token_pos(), value);
}
@ -1961,8 +1965,9 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
node->operand()->Visit(&for_value);
Append(for_value);
Value* value = for_value.value();
if (Isolate::Current()->TypeChecksEnabled() ||
Isolate::Current()->AssertsEnabled()) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() ||
isolate->flags().asserts()) {
value =
Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
}
@ -3565,7 +3570,7 @@ void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
node->value()->Visit(&for_value);
Append(for_value);
Value* store_value = for_value.value();
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
store_value = BuildAssignableValue(node->value()->token_pos(),
store_value,
node->local().type(),
@ -3606,7 +3611,7 @@ void EffectGraphVisitor::VisitStoreInstanceFieldNode(
node->value()->Visit(&for_value);
Append(for_value);
Value* store_value = for_value.value();
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const AbstractType& type =
AbstractType::ZoneHandle(Z, node->field().type());
const String& dst_name = String::ZoneHandle(Z, node->field().name());
@ -3997,7 +4002,7 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
}
}
if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) {
if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) {
const int num_params = function.NumParameters();
int pos = 0;
if (function.IsGenerativeConstructor()) {

View file

@ -980,7 +980,7 @@ void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) {
void FlowGraphCompiler::TryIntrinsify() {
// Intrinsification skips arguments checks, therefore disable if in checked
// mode.
if (FLAG_intrinsify && !isolate()->TypeChecksEnabled()) {
if (FLAG_intrinsify && !isolate()->flags().type_checks()) {
if (parsed_function().function().kind() == RawFunction::kImplicitGetter) {
// An implicit getter must have a specific AST structure.
const SequenceNode& sequence_node = *parsed_function().node_sequence();

View file

@ -1231,7 +1231,7 @@ bool FlowGraphOptimizer::InlineSetIndexed(
call->GetBlock()->try_index());
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
if (I->TypeChecksEnabled()) {
if (I->flags().type_checks()) {
// Only type check for the value. A type check for the index is not
// needed here because we insert a deoptimizing smi-check for the case
// the index is not a smi.
@ -4570,7 +4570,7 @@ bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
const ICData& unary_ic_data) {
ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
(unary_ic_data.NumArgsTested() == 1));
if (I->TypeChecksEnabled()) {
if (I->flags().type_checks()) {
// Checked mode setters are inlined like normal methods by conventional
// inlining.
return false;

View file

@ -38,7 +38,7 @@ FlowGraphTypePropagator::FlowGraphTypePropagator(FlowGraph* flow_graph)
types_.Add(NULL);
}
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
asserts_ = new ZoneGrowableArray<AssertAssignableInstr*>(
flow_graph->current_ssa_temp_index());
for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) {
@ -120,7 +120,7 @@ void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
const intptr_t rollback_point = rollback_.length();
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
StrengthenAsserts(block);
}
@ -921,7 +921,7 @@ CompileType StaticCallInstr::ComputeType() const {
return CompileType::FromCid(result_cid_);
}
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
// Void functions are known to return null, which is checked at the return
// from the function.
const AbstractType& result_type =
@ -936,7 +936,7 @@ CompileType StaticCallInstr::ComputeType() const {
CompileType LoadLocalInstr::ComputeType() const {
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
return CompileType::FromAbstractType(local().type());
}
return CompileType::Dynamic();
@ -980,7 +980,7 @@ CompileType LoadStaticFieldInstr::ComputeType() const {
intptr_t cid = kDynamicCid;
AbstractType* abstract_type = NULL;
const Field& field = this->StaticField();
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
cid = kIllegalCid;
abstract_type = &AbstractType::ZoneHandle(field.type());
}
@ -1038,7 +1038,7 @@ CompileType LoadFieldInstr::ComputeType() const {
}
const AbstractType* abstract_type = NULL;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
ASSERT(!type().HasResolvedTypeClass() ||
!Field::IsExternalizableCid(Class::Handle(
type().type_class()).id()));

View file

@ -2029,7 +2029,7 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraph* flow_graph) {
Definition* InstantiateTypeArgumentsInstr::Canonicalize(FlowGraph* flow_graph) {
return (Isolate::Current()->TypeChecksEnabled() || HasUses()) ? this : NULL;
return (Isolate::Current()->flags().type_checks() || HasUses()) ? this : NULL;
}

View file

@ -25,7 +25,6 @@
namespace dart {
DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, use_osr);
@ -374,13 +373,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
__ CompareObject(reg, Bool::True());
__ b(&done, EQ);
__ CompareObject(reg, Bool::False());
__ b(&done, EQ);
} else {
ASSERT(FLAG_enable_asserts);
ASSERT(Isolate::Current()->flags().asserts());
__ CompareObject(reg, Object::null_instance());
__ b(&done, NE);
}

View file

@ -24,7 +24,6 @@
namespace dart {
DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, use_osr);
@ -362,13 +361,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
__ CompareObject(reg, Bool::True(), PP);
__ b(&done, EQ);
__ CompareObject(reg, Bool::False(), PP);
__ b(&done, EQ);
} else {
ASSERT(FLAG_enable_asserts);
ASSERT(Isolate::Current()->flags().asserts());
__ CompareObject(reg, Object::null_instance(), PP);
__ b(&done, NE);
}

View file

@ -23,7 +23,6 @@
namespace dart {
DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, use_osr);
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
@ -249,13 +248,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
__ CompareObject(reg, Bool::True());
__ j(EQUAL, &done, Assembler::kNearJump);
__ CompareObject(reg, Bool::False());
__ j(EQUAL, &done, Assembler::kNearJump);
} else {
ASSERT(FLAG_enable_asserts);
ASSERT(Isolate::Current()->flags().asserts());
__ CompareObject(reg, Object::null_instance());
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
}

View file

@ -24,7 +24,6 @@
namespace dart {
DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, use_osr);
@ -427,11 +426,11 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
__ BranchEqual(reg, Bool::True(), &done);
__ BranchEqual(reg, Bool::False(), &done);
} else {
ASSERT(FLAG_enable_asserts);
ASSERT(Isolate::Current()->flags().asserts());
__ BranchNotEqual(reg, Object::null_instance(), &done);
}

View file

@ -23,7 +23,6 @@
namespace dart {
DECLARE_FLAG(bool, emit_edge_counters);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
DECLARE_FLAG(bool, use_osr);
@ -330,13 +329,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
__ CompareObject(reg, Bool::True(), PP);
__ j(EQUAL, &done, Assembler::kNearJump);
__ CompareObject(reg, Bool::False(), PP);
__ j(EQUAL, &done, Assembler::kNearJump);
} else {
ASSERT(FLAG_enable_asserts);
ASSERT(Isolate::Current()->flags().asserts());
__ CompareObject(reg, Object::null_instance(), PP);
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
}

View file

@ -594,7 +594,7 @@ bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
return false;
}

View file

@ -50,7 +50,7 @@ static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
Label fall_through;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const intptr_t type_args_field_offset =
ComputeObjectArrayTypeArgumentsOffset();
// Inline simple tests (Smi, null), fallthrough if not positive.
@ -153,7 +153,7 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
// On stack: growable array (+1), value (+0).
void Intrinsifier::GrowableArray_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
return;
}
Label fall_through;

View file

@ -48,7 +48,7 @@ static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
Label fall_through;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const intptr_t type_args_field_offset =
ComputeObjectArrayTypeArgumentsOffset();
// Inline simple tests (Smi, null), fallthrough if not positive.
@ -149,7 +149,7 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
// On stack: growable array (+1), value (+0).
void Intrinsifier::GrowableArray_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
return;
}
Label fall_through;

View file

@ -54,7 +54,7 @@ static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
// update. Array length is always a Smi.
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
Label fall_through;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const intptr_t type_args_field_offset =
ComputeObjectArrayTypeArgumentsOffset();
// Inline simple tests (Smi, null), fallthrough if not positive.
@ -155,7 +155,7 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
// On stack: growable array (+2), value (+1), return-address (+0).
void Intrinsifier::GrowableArray_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (Isolate::Current()->TypeChecksEnabled()) return;
if (Isolate::Current()->flags().type_checks()) return;
Label fall_through;
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.

View file

@ -48,7 +48,7 @@ static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
Label fall_through;
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
const intptr_t type_args_field_offset =
ComputeObjectArrayTypeArgumentsOffset();
// Inline simple tests (Smi, null), fallthrough if not positive.
@ -145,7 +145,7 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
// On stack: growable array (+1), value (+0).
void Intrinsifier::GrowableArray_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (Isolate::Current()->TypeChecksEnabled()) return;
if (Isolate::Current()->flags().type_checks()) return;
Label fall_through;
__ lw(T0, Address(SP, 1 * kWordSize)); // Array.
__ lw(T1, FieldAddress(T0, GrowableObjectArray::length_offset()));

View file

@ -32,7 +32,7 @@ intptr_t Intrinsifier::ParameterSlotFromSp() { return 0; }
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
if (Isolate::Current()->TypeChecksEnabled()) {
if (Isolate::Current()->flags().type_checks()) {
return;
}
__ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
@ -101,7 +101,7 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
// On stack: growable array (+2), value (+1), return-address (+0).
void Intrinsifier::GrowableArray_add(Assembler* assembler) {
// In checked mode we need to check the incoming argument.
if (Isolate::Current()->TypeChecksEnabled()) return;
if (Isolate::Current()->flags().type_checks()) return;
Label fall_through;
__ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
__ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));

View file

@ -54,6 +54,32 @@ DEFINE_FLAG(charp, isolate_log_filter, NULL,
"Log isolates whose name include the filter. "
"Default: service isolate log messages are suppressed.");
// TODO(iposva): Make these isolate specific flags inaccessible using the
// regular FLAG_xyz pattern.
// These flags are per-isolate and only influence the defaults.
DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
DEFINE_FLAG(bool, error_on_bad_override, false,
"Report error for bad overrides.");
DEFINE_FLAG(bool, error_on_bad_type, false,
"Report error for malformed types.");
static void CheckedModeHandler(bool value) {
FLAG_enable_asserts = value;
FLAG_enable_type_checks = value;
}
// --enable-checked-mode and --checked both enable checked mode which is
// equivalent to setting --enable-asserts and --enable-type-checks.
DEFINE_FLAG_HANDLER(CheckedModeHandler,
enable_checked_mode,
"Enable checked mode.");
DEFINE_FLAG_HANDLER(CheckedModeHandler,
checked,
"Enable checked mode.");
// Quick access to the locally defined isolate() method.
#define I (isolate())
@ -536,6 +562,35 @@ bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
}
Isolate::Flags::Flags()
: type_checks_(FLAG_enable_type_checks),
asserts_(FLAG_enable_asserts),
error_on_bad_type_(FLAG_error_on_bad_type),
error_on_bad_override_(FLAG_error_on_bad_override) {}
void Isolate::Flags::CopyFrom(const Flags& orig) {
type_checks_ = orig.type_checks();
asserts_ = orig.asserts();
error_on_bad_type_ = orig.error_on_bad_type();
error_on_bad_override_ = orig.error_on_bad_override();
}
void Isolate::Flags::CopyFrom(const Dart_IsolateFlags& api_flags) {
type_checks_ = api_flags.enable_type_checks;
asserts_ = api_flags.enable_asserts;
// Leave others at defaults.
}
void Isolate::Flags::CopyTo(Dart_IsolateFlags* api_flags) const {
api_flags->version = DART_FLAGS_CURRENT_VERSION;
api_flags->enable_type_checks = type_checks();
api_flags->enable_asserts = asserts();
}
#if defined(DEBUG)
// static
void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
@ -553,7 +608,7 @@ void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
#define REUSABLE_HANDLE_INITIALIZERS(object) \
object##_handle_(NULL),
Isolate::Isolate()
Isolate::Isolate(const Dart_IsolateFlags& api_flags)
: mutator_thread_(NULL),
vm_tag_(0),
store_buffer_(),
@ -578,7 +633,7 @@ Isolate::Isolate()
single_step_(false),
resume_request_(false),
has_compiled_(false),
strict_compilation_(false),
flags_(),
random_(),
simulator_(NULL),
long_jump_base_(NULL),
@ -620,6 +675,7 @@ Isolate::Isolate()
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
reusable_handles_() {
flags_.CopyFrom(api_flags);
set_vm_tag(VMTag::kEmbedderTagId);
set_user_tag(UserTags::kDefaultUserTag);
}
@ -671,8 +727,10 @@ void Isolate::InitOnce() {
}
Isolate* Isolate::Init(const char* name_prefix, bool is_vm_isolate) {
Isolate* result = new Isolate();
Isolate* Isolate::Init(const char* name_prefix,
const Dart_IsolateFlags& api_flags,
bool is_vm_isolate) {
Isolate* result = new Isolate(api_flags);
ASSERT(result != NULL);
// Initialize metrics.
@ -1803,8 +1861,7 @@ static RawInstance* DeserializeObject(Isolate* isolate,
IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
const Function& func,
const Instance& message,
bool paused,
bool checkedFlag)
bool paused)
: isolate_(NULL),
parent_port_(parent_port),
script_url_(NULL),
@ -1816,8 +1873,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
serialized_args_len_(0),
serialized_message_(NULL),
serialized_message_len_(0),
paused_(paused),
checked_(checkedFlag) {
isolate_flags_(),
paused_(paused) {
script_url_ = NULL;
const Class& cls = Class::Handle(func.Owner());
const Library& lib = Library::Handle(cls.library());
@ -1835,6 +1892,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
&serialized_message_,
&serialized_message_len_,
can_send_any_object);
// Inherit flags from spawning isolate.
isolate_flags()->CopyFrom(Isolate::Current()->flags());
}
@ -1843,8 +1902,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
const char* package_root,
const Instance& args,
const Instance& message,
bool paused,
bool checkedFlag)
bool paused)
: isolate_(NULL),
parent_port_(parent_port),
package_root_(NULL),
@ -1855,8 +1913,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
serialized_args_len_(0),
serialized_message_(NULL),
serialized_message_len_(0),
paused_(paused),
checked_(checkedFlag) {
isolate_flags_(),
paused_(paused) {
script_url_ = strdup(script_url);
if (package_root != NULL) {
package_root_ = strdup(package_root);
@ -1872,6 +1930,9 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
&serialized_message_,
&serialized_message_len_,
can_send_any_object);
// By default inherit flags from spawning isolate. These can be overridden
// from the calling code.
isolate_flags()->CopyFrom(Isolate::Current()->flags());
}

View file

@ -23,11 +23,6 @@
namespace dart {
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, enable_asserts);
DECLARE_FLAG(bool, error_on_bad_type);
DECLARE_FLAG(bool, error_on_bad_override);
// Forward declarations.
class AbstractType;
class ApiState;
@ -126,7 +121,9 @@ class Isolate : public BaseIsolate {
}
static void InitOnce();
static Isolate* Init(const char* name_prefix, bool is_vm_isolate = false);
static Isolate* Init(const char* name_prefix,
const Dart_IsolateFlags& api_flags,
bool is_vm_isolate = false);
void Shutdown();
// Register a newly introduced class.
@ -383,19 +380,51 @@ class Isolate : public BaseIsolate {
void set_has_compiled(bool value) { has_compiled_ = value; }
bool has_compiled() const { return has_compiled_; }
void set_strict_compilation(bool value) { strict_compilation_ = value; }
bool strict_compilation() const { return strict_compilation_; }
bool TypeChecksEnabled() {
return FLAG_enable_type_checks || strict_compilation_;
}
bool AssertsEnabled() {
return FLAG_enable_asserts || strict_compilation_;
}
bool ErrorOnBadTypeEnabled() {
return FLAG_error_on_bad_type || strict_compilation_;
}
bool ErrorOnBadOverrideEnabled() {
return FLAG_error_on_bad_override || strict_compilation_;
// TODO(iposva): Evaluate whether two different isolate flag structures are
// needed. Currently it serves as a separation between publicly visible flags
// and VM internal flags.
class Flags : public ValueObject {
public:
// Construct default flags as specified by the options.
Flags();
bool type_checks() const { return type_checks_; }
bool asserts() const { return asserts_; }
bool error_on_bad_type() const { return error_on_bad_type_; }
bool error_on_bad_override() const { return error_on_bad_override_; }
void set_checked(bool val) {
type_checks_ = val;
asserts_ = val;
}
void CopyFrom(const Flags& orig);
void CopyFrom(const Dart_IsolateFlags& api_flags);
void CopyTo(Dart_IsolateFlags* api_flags) const;
private:
bool type_checks_;
bool asserts_;
bool error_on_bad_type_;
bool error_on_bad_override_;
friend class Isolate;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(Flags);
};
const Flags& flags() const { return flags_; }
// Set the checks in the compiler to the highest level. Statically and when
// executing generated code. Needs to be called before any code has been
// compiled.
void set_strict_compilation() {
ASSERT(!has_compiled());
flags_.type_checks_ = true;
flags_.asserts_ = true;
flags_.error_on_bad_type_ = true;
flags_.error_on_bad_override_ = true;
}
// Requests that the debugger resume execution.
@ -677,7 +706,7 @@ class Isolate : public BaseIsolate {
void PauseEventHandler();
private:
Isolate();
explicit Isolate(const Dart_IsolateFlags& api_flags);
void BuildName(const char* name_prefix);
void PrintInvokedFunctions();
@ -720,7 +749,7 @@ class Isolate : public BaseIsolate {
bool single_step_;
bool resume_request_;
bool has_compiled_;
bool strict_compilation_;
Flags flags_;
Random random_;
Simulator* simulator_;
LongJumpScope* long_jump_base_;
@ -926,15 +955,13 @@ class IsolateSpawnState {
IsolateSpawnState(Dart_Port parent_port,
const Function& func,
const Instance& message,
bool paused,
bool checked);
bool paused);
IsolateSpawnState(Dart_Port parent_port,
const char* script_url,
const char* package_root,
const Instance& args,
const Instance& message,
bool paused,
bool checked);
bool paused);
~IsolateSpawnState();
Isolate* isolate() const { return isolate_; }
@ -948,7 +975,7 @@ class IsolateSpawnState {
char* function_name() const { return function_name_; }
bool is_spawn_uri() const { return library_url_ == NULL; }
bool paused() const { return paused_; }
bool checked_mode() const { return checked_; }
Isolate::Flags* isolate_flags() { return &isolate_flags_; }
RawObject* ResolveFunction();
RawInstance* BuildArgs(Zone* zone);
@ -967,8 +994,8 @@ class IsolateSpawnState {
intptr_t serialized_args_len_;
uint8_t* serialized_message_;
intptr_t serialized_message_len_;
Isolate::Flags isolate_flags_;
bool paused_;
bool checked_;
};
} // namespace dart

View file

@ -10,7 +10,10 @@
namespace dart {
UNIT_TEST_CASE(IsolateCurrent) {
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT_EQ(isolate, Isolate::Current());
isolate->Shutdown();
EXPECT_EQ(reinterpret_cast<Isolate*>(NULL), Isolate::Current());

View file

@ -14,7 +14,10 @@
namespace dart {
UNIT_TEST_CASE(Metric_Simple) {
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT_EQ(isolate, Isolate::Current());
Metric metric;
@ -40,7 +43,10 @@ class MyMetric : public Metric {
};
UNIT_TEST_CASE(Metric_OnDemand) {
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT_EQ(isolate, Isolate::Current());
MyMetric metric;

View file

@ -65,7 +65,6 @@ DEFINE_FLAG(bool, use_field_guards, true, "Guard field cids.");
DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache");
DEFINE_FLAG(bool, trace_field_guards, false, "Trace changes in field's cids.");
DECLARE_FLAG(bool, error_on_bad_override);
DECLARE_FLAG(bool, trace_compiler);
DECLARE_FLAG(bool, trace_deoptimization);
DECLARE_FLAG(bool, trace_deoptimization_verbose);
@ -5115,6 +5114,7 @@ bool Function::HasCode() const {
void Function::ClearCode() const {
ASSERT(ic_data_array() == Array::null());
StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
StubCode* stub_code = Isolate::Current()->stub_code();
StorePointer(&raw_ptr()->instructions_,
@ -5141,8 +5141,9 @@ void Function::SwitchToUnoptimizedCode() const {
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
AttachCode(Code::Handle(zone, unoptimized_code()));
CodePatcher::RestoreEntry(Code::Handle(zone, unoptimized_code()));
const Code& unopt_code = Code::Handle(zone, unoptimized_code());
AttachCode(unopt_code);
CodePatcher::RestoreEntry(unopt_code);
isolate->TrackDeoptimizedCode(current_code);
}
@ -5906,7 +5907,7 @@ const char* Function::ToQualifiedCString() const {
bool Function::HasCompatibleParametersWith(const Function& other,
Error* bound_error) const {
ASSERT(Isolate::Current()->ErrorOnBadOverrideEnabled());
ASSERT(Isolate::Current()->flags().error_on_bad_override());
ASSERT((bound_error != NULL) && bound_error->IsNull());
// Check that this function's signature type is a subtype of the other
// function's signature type.
@ -6198,13 +6199,13 @@ RawFunction* Function::Clone(const Class& new_owner) const {
const PatchClass& clone_owner =
PatchClass::Handle(PatchClass::New(new_owner, origin));
clone.set_owner(clone_owner);
clone.ClearICDataArray();
clone.ClearCode();
clone.set_usage_counter(0);
clone.set_deoptimization_counter(0);
clone.set_regexp_cid(kIllegalCid);
clone.set_optimized_instruction_count(0);
clone.set_optimized_call_site_count(0);
clone.set_ic_data_array(Array::Handle());
if (new_owner.NumTypeParameters() > 0) {
// Adjust uninstantiated types to refer to type parameters of the new owner.
AbstractType& type = AbstractType::Handle(clone.result_type());
@ -6755,7 +6756,7 @@ RawArray* Function::ic_data_array() const {
}
void Function::ClearICDataArray() const {
set_ic_data_array(Array::Handle());
set_ic_data_array(Array::null_array());
}
@ -13952,7 +13953,7 @@ bool Instance::IsInstanceOf(const AbstractType& other,
const AbstractType& instantiated_other = AbstractType::Handle(
isolate, other.InstantiateFrom(other_instantiator, bound_error));
if ((bound_error != NULL) && !bound_error->IsNull()) {
ASSERT(Isolate::Current()->TypeChecksEnabled());
ASSERT(Isolate::Current()->flags().type_checks());
return false;
}
other_class = instantiated_other.type_class();
@ -14619,14 +14620,14 @@ bool AbstractType::TypeTest(TypeTestKind test_kind,
// type and/or malbounded parameter types, which will then be encountered here
// at run time.
if (IsMalbounded()) {
ASSERT(Isolate::Current()->TypeChecksEnabled());
ASSERT(Isolate::Current()->flags().type_checks());
if ((bound_error != NULL) && bound_error->IsNull()) {
*bound_error = error();
}
return false;
}
if (other.IsMalbounded()) {
ASSERT(Isolate::Current()->TypeChecksEnabled());
ASSERT(Isolate::Current()->flags().type_checks());
if ((bound_error != NULL) && bound_error->IsNull()) {
*bound_error = other.error();
}
@ -14833,7 +14834,7 @@ bool Type::IsMalformed() const {
bool Type::IsMalbounded() const {
if (!Isolate::Current()->TypeChecksEnabled()) {
if (!Isolate::Current()->flags().type_checks()) {
return false;
}
if (raw_ptr()->error_ == LanguageError::null()) {
@ -14853,7 +14854,7 @@ bool Type::IsMalformedOrMalbounded() const {
return true;
}
ASSERT(type_error.kind() == Report::kMalboundedType);
return Isolate::Current()->TypeChecksEnabled();
return Isolate::Current()->flags().type_checks();
}
@ -15857,7 +15858,7 @@ RawAbstractType* BoundedType::InstantiateFrom(
bound_error,
trail);
}
if ((Isolate::Current()->TypeChecksEnabled()) &&
if ((Isolate::Current()->flags().type_checks()) &&
(bound_error != NULL) && bound_error->IsNull()) {
AbstractType& upper_bound = AbstractType::Handle(bound());
ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());

View file

@ -37,32 +37,14 @@
namespace dart {
DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\".");
DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
DEFINE_FLAG(bool, load_deferred_eagerly, false,
"Load deferred libraries eagerly.");
DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
DECLARE_FLAG(bool, error_on_bad_type);
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
DECLARE_FLAG(bool, warn_on_javascript_compatibility);
static void CheckedModeHandler(bool value) {
FLAG_enable_asserts = value;
FLAG_enable_type_checks = value;
}
// --enable-checked-mode and --checked both enable checked mode which is
// equivalent to setting --enable-asserts and --enable-type-checks.
DEFINE_FLAG_HANDLER(CheckedModeHandler,
enable_checked_mode,
"Enable checked mode.");
DEFINE_FLAG_HANDLER(CheckedModeHandler,
checked,
"Enable checked mode.");
// Quick access to the current isolate and zone.
#define I (isolate())
@ -3230,7 +3212,7 @@ SequenceNode* Parser::ParseFunc(const Function& func,
// Populate function scope with the formal parameters.
AddFormalParamsToScope(&params, current_block_->scope);
if (I->TypeChecksEnabled() &&
if (I->flags().type_checks() &&
(current_block_->scope->function_level() > 0)) {
// We are parsing, but not compiling, a local function.
// The instantiator may be required at run time for generic type checks.
@ -7282,7 +7264,7 @@ AstNode* Parser::ParseVariableDeclarationList() {
bool is_final = (CurrentToken() == Token::kFINAL);
bool is_const = (CurrentToken() == Token::kCONST);
const AbstractType& type = AbstractType::ZoneHandle(Z,
ParseConstFinalVarOrType(I->TypeChecksEnabled() ?
ParseConstFinalVarOrType(I->flags().type_checks() ?
ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore));
if (!IsIdentifier()) {
ReportError("identifier expected");
@ -8391,8 +8373,8 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
// position, which is inside the loop body.
new_loop_var = true;
loop_var_type = ParseConstFinalVarOrType(
I->TypeChecksEnabled() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
I->flags().type_checks() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
}
intptr_t loop_var_pos = TokenPos();
const String* loop_var_name = ExpectIdentifier("variable name expected");
@ -8671,8 +8653,8 @@ AstNode* Parser::ParseForInStatement(intptr_t forin_pos,
// position, which is inside the loop body.
new_loop_var = true;
loop_var_type = ParseConstFinalVarOrType(
I->TypeChecksEnabled() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
I->flags().type_checks() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
loop_var_name = ExpectIdentifier("variable name expected");
}
ExpectToken(Token::kIN);
@ -8890,7 +8872,7 @@ AstNode* Parser::ParseAssertStatement() {
ConsumeToken(); // Consume assert keyword.
ExpectToken(Token::kLPAREN);
const intptr_t condition_pos = TokenPos();
if (!I->AssertsEnabled() && !I->TypeChecksEnabled()) {
if (!I->flags().asserts() && !I->flags().type_checks()) {
SkipExpr();
ExpectToken(Token::kRPAREN);
return NULL;
@ -12083,7 +12065,7 @@ AstNode* Parser::ParseListLiteral(intptr_t type_pos,
"include a type variable");
}
} else {
if (I->ErrorOnBadTypeEnabled()) {
if (I->flags().error_on_bad_type()) {
ReportError(type_pos,
"a list literal takes one type argument specifying "
"the element type");
@ -12106,7 +12088,7 @@ AstNode* Parser::ParseListLiteral(intptr_t type_pos,
while (CurrentToken() != Token::kRBRACK) {
const intptr_t element_pos = TokenPos();
AstNode* element = ParseExpr(is_const, kConsumeCascades);
if (I->TypeChecksEnabled() &&
if (I->flags().type_checks() &&
!is_const &&
!element_type.IsDynamicType()) {
element = new(Z) AssignableNode(element_pos,
@ -12137,7 +12119,7 @@ AstNode* Parser::ParseListLiteral(intptr_t type_pos,
// Arguments have been evaluated to a literal value already.
ASSERT(elem->IsLiteralNode());
ASSERT(!is_top_level_); // We cannot check unresolved types.
if (I->TypeChecksEnabled() &&
if (I->flags().type_checks() &&
!element_type.IsDynamicType() &&
(!elem->AsLiteralNode()->literal().IsNull() &&
!elem->AsLiteralNode()->literal().IsInstanceOf(
@ -12280,7 +12262,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
"include a type variable");
}
} else {
if (I->ErrorOnBadTypeEnabled()) {
if (I->flags().error_on_bad_type()) {
ReportError(type_pos,
"a map literal takes two type arguments specifying "
"the key type and the value type");
@ -12299,7 +12281,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
const bool saved_mode = SetAllowFunctionLiterals(true);
const intptr_t key_pos = TokenPos();
AstNode* key = ParseExpr(is_const, kConsumeCascades);
if (I->TypeChecksEnabled() &&
if (I->flags().type_checks() &&
!is_const &&
!key_type.IsDynamicType()) {
key = new(Z) AssignableNode(
@ -12322,7 +12304,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
const intptr_t value_pos = TokenPos();
AstNode* value = ParseExpr(is_const, kConsumeCascades);
SetAllowFunctionLiterals(saved_mode);
if (I->TypeChecksEnabled() &&
if (I->flags().type_checks() &&
!is_const &&
!value_type.IsDynamicType()) {
value = new(Z) AssignableNode(
@ -12354,7 +12336,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
// Arguments have been evaluated to a literal value already.
ASSERT(arg->IsLiteralNode());
ASSERT(!is_top_level_); // We cannot check unresolved types.
if (I->TypeChecksEnabled()) {
if (I->flags().type_checks()) {
if ((i % 2) == 0) {
// Check key type.
arg_type = key_type.raw();
@ -12679,7 +12661,7 @@ AstNode* Parser::ParseNewOperator(Token::Kind op_kind) {
}
return ThrowTypeError(redirect_type.token_pos(), redirect_type);
}
if (I->TypeChecksEnabled() && !redirect_type.IsSubtypeOf(type, NULL)) {
if (I->flags().type_checks() && !redirect_type.IsSubtypeOf(type, NULL)) {
// Additional type checking of the result is necessary.
type_bound = type.raw();
}

View file

@ -722,8 +722,8 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
}
// Initialize all fields that are not part of the snapshot.
func.ClearICDataArray();
func.ClearCode();
func.set_ic_data_array(Object::null_array());
return func.raw();
}

View file

@ -2605,8 +2605,8 @@ static bool GetVM(Isolate* isolate, JSONStream* js) {
// pids > 53-bits (when consumed by JavaScript).
// TODO(johnmccutchan): Codify how integers are sent across the service.
jsobj.AddPropertyF("pid", "%" Pd "", OS::ProcessId());
jsobj.AddProperty("_assertsEnabled", isolate->AssertsEnabled());
jsobj.AddProperty("_typeChecksEnabled", isolate->TypeChecksEnabled());
jsobj.AddProperty("_assertsEnabled", isolate->flags().asserts());
jsobj.AddProperty("_typeChecksEnabled", isolate->flags().type_checks());
int64_t start_time_millis = (Dart::vm_isolate()->start_time() /
kMicrosecondsPerMillisecond);
jsobj.AddProperty64("startTime", start_time_millis);

View file

@ -625,10 +625,15 @@ class RunServiceTask : public ThreadPool::Task {
return;
}
Isolate::Flags default_flags;
Dart_IsolateFlags api_flags;
default_flags.CopyTo(&api_flags);
isolate =
reinterpret_cast<Isolate*>(create_callback(ServiceIsolate::kName,
NULL,
NULL,
&api_flags,
NULL,
&error));
if (isolate == NULL) {

View file

@ -12,7 +12,10 @@ namespace dart {
UNIT_TEST_CASE(Mutex) {
// This unit test case needs a running isolate.
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
Mutex* mutex = new Mutex();
mutex->Lock();
@ -34,7 +37,10 @@ UNIT_TEST_CASE(Mutex) {
UNIT_TEST_CASE(Monitor) {
// This unit test case needs a running isolate.
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
// Thread interrupter interferes with this test, disable interrupts.
isolate->set_thread_state(NULL);
Profiler::EndExecution(isolate);

View file

@ -286,7 +286,8 @@ class TestCase : TestCaseBase {
static Dart_Isolate CreateIsolate(const uint8_t* buffer,
const char* name) {
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(name, NULL, buffer, NULL, &err);
Dart_Isolate isolate = Dart_CreateIsolate(
name, NULL, buffer, NULL, NULL, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);
free(err);

View file

@ -16,7 +16,10 @@ UNIT_TEST_CASE(AllocateZone) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT(Isolate::Current() == isolate);
EXPECT(isolate->current_zone() == NULL);
{
@ -78,7 +81,10 @@ UNIT_TEST_CASE(AllocGeneric_Success) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT(Isolate::Current() == isolate);
EXPECT(isolate->current_zone() == NULL);
{
@ -102,7 +108,10 @@ UNIT_TEST_CASE(AllocGeneric_Overflow) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT(Isolate::Current() == isolate);
EXPECT(isolate->current_zone() == NULL);
{
@ -121,7 +130,10 @@ UNIT_TEST_CASE(ZoneAllocated) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Isolate* isolate = Isolate::Init(NULL);
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate* isolate = Isolate::Init(NULL, api_flags);
EXPECT(Isolate::Current() == isolate);
EXPECT(isolate->current_zone() == NULL);
static int marker;

View file

@ -5,7 +5,6 @@
[ $runtime == vm ]
browser/*: SkipByDesign # Browser specific tests
isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
checked_test: Skip # Issue 23578
[ $runtime != vm ]
checked_test: Skip # Unsupported.