- Remove Isolate::Flags structure and store flags directly in isolate.

- Make enable_asserts, enable_type_checks, error_on_bad_override and
  error_on_bad_type release mode flags only.

BUG=
R=fschneider@google.com

Review URL: https://codereview.chromium.org/1737693003 .
This commit is contained in:
Ivan Posva 2016-02-25 18:06:56 -08:00
parent 47b2253866
commit 8d18298fed
34 changed files with 154 additions and 173 deletions

View file

@ -151,8 +151,8 @@ class SpawnIsolateTask : public ThreadPool::Task {
return;
}
Dart_IsolateFlags api_flags;
state_->isolate_flags()->CopyTo(&api_flags);
// Make a copy of the state's isolate flags and hand it to the callback.
Dart_IsolateFlags api_flags = *(state_->isolate_flags());
Isolate* isolate = reinterpret_cast<Isolate*>(
(callback)(state_->script_url(),
@ -391,7 +391,10 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) {
// 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());
bool val = checked.value();
Dart_IsolateFlags* flags = state->isolate_flags();
flags->enable_asserts = val;
flags->enable_type_checks = val;
}
ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);

View file

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

View file

@ -104,7 +104,9 @@ def Main():
return 1
# Setup arguments to the snapshot generator binary.
script_args = ["--error_on_bad_type", "--error_on_bad_override"]
script_args = ["--ignore_unrecognized_flags",
"--error_on_bad_type",
"--error_on_bad_override"]
# Pass along the package_root if there is one.
if options.package_root:

View file

@ -2760,7 +2760,7 @@ bool AotOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
const ICData& unary_ic_data) {
ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
(unary_ic_data.NumArgsTested() == 1));
if (I->flags().type_checks()) {
if (I->type_checks()) {
// Checked mode setters are inlined like normal methods by conventional
// inlining.
return false;

View file

@ -575,7 +575,7 @@ AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) {
if (field().is_final()) {
return NULL;
}
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
rhs = new AssignableNode(
field().token_pos(),
rhs,
@ -663,7 +663,7 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
if (!field.is_final()) {
if (isolate->flags().type_checks()) {
if (isolate->type_checks()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(zone, field.type()),
@ -698,7 +698,7 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
if (!field.is_final()) {
if (isolate->flags().type_checks()) {
if (isolate->type_checks()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(zone, field.type()),
@ -754,7 +754,7 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
ASSERT(!getter.IsNull() &&
(getter.kind() == RawFunction::kImplicitStaticFinalGetter));
#endif
if (isolate->flags().type_checks()) {
if (isolate->type_checks()) {
rhs = new AssignableNode(
field.token_pos(),
rhs,

View file

@ -389,7 +389,7 @@ void ClassFinalizer::ResolveRedirectingFactoryTarget(
return;
}
if (Isolate::Current()->flags().error_on_bad_override()) {
if (Isolate::Current()->error_on_bad_override()) {
// Verify that the target is compatible with the redirecting factory.
Error& error = Error::Handle();
if (!target.HasCompatibleParametersWith(factory, &error)) {
@ -677,7 +677,7 @@ intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments(
TypeArguments& arguments = TypeArguments::Handle(Z, 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()->flags().error_on_bad_type()) {
if (Isolate::Current()->error_on_bad_type()) {
const String& type_class_name = String::Handle(Z, type_class.Name());
ReportError(cls, type.token_pos(),
"wrong number of type arguments for class '%s'",
@ -1456,7 +1456,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
!const_value.IsInstanceOf(type,
Object::null_type_arguments(),
&error))) {
if (Isolate::Current()->flags().error_on_bad_type()) {
if (Isolate::Current()->error_on_bad_type()) {
const AbstractType& const_value_type = AbstractType::Handle(
Z, const_value.GetType());
const String& const_value_type_name = String::Handle(
@ -1519,7 +1519,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
FinalizeSignature(cls, function);
name = function.name();
// Report signature conflicts only.
if (Isolate::Current()->flags().error_on_bad_override() &&
if (Isolate::Current()->error_on_bad_override() &&
!function.is_static() && !function.IsGenerativeConstructor()) {
// A constructor cannot override anything.
for (intptr_t i = 0; i < interfaces.length(); i++) {
@ -2710,7 +2710,7 @@ void ClassFinalizer::CollectTypeArguments(
}
return;
}
if (Isolate::Current()->flags().error_on_bad_type()) {
if (Isolate::Current()->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'",
@ -3142,7 +3142,7 @@ void ClassFinalizer::MarkTypeMalformed(const Error& prev_error,
prev_error, script, type.token_pos(), Report::AtLocation,
Report::kMalformedType, Heap::kOld,
format, args));
if (Isolate::Current()->flags().error_on_bad_type()) {
if (Isolate::Current()->error_on_bad_type()) {
ReportError(error);
}
type.set_error(error);
@ -3204,7 +3204,7 @@ void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error,
Report::kMalboundedType, Heap::kOld,
format, args));
va_end(args);
if (Isolate::Current()->flags().error_on_bad_type()) {
if (Isolate::Current()->error_on_bad_type()) {
ReportError(error);
}
type.set_error(error);

View file

@ -232,7 +232,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->flags().type_checks()) {
if (isolate->type_checks()) {
Error& bound_error = Error::Handle();
type_arguments =
type_arguments.InstantiateAndCanonicalizeFrom(instantiator,
@ -537,7 +537,7 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 5) {
}
String& bound_error_message = String::Handle();
if (!bound_error.IsNull()) {
ASSERT(isolate->flags().type_checks());
ASSERT(isolate->type_checks());
bound_error_message = String::New(bound_error.ToErrorCString());
}
if (src_type_name.Equals(dst_type_name)) {

View file

@ -123,7 +123,6 @@ TEST_CASE(RegenerateAllocStubs) {
" return unOpt();\n"
"}\n";
// 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);

View file

@ -131,9 +131,8 @@ const char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot,
const bool precompiled = instructions_snapshot != NULL;
// Setup default flags for the VM isolate.
Isolate::Flags vm_flags;
Dart_IsolateFlags api_flags;
vm_flags.CopyTo(&api_flags);
Isolate::FlagsInitialize(&api_flags);
vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate);
start_time_ = vm_isolate_->start_time();
vm_isolate_->set_compilation_allowed(!precompiled);

View file

@ -1240,8 +1240,7 @@ DART_EXPORT Dart_Isolate Dart_CreateIsolate(const char* script_uri,
// Setup default flags in case none were passed.
Dart_IsolateFlags api_flags;
if (flags == NULL) {
Isolate::Flags vm_flags;
vm_flags.CopyTo(&api_flags);
Isolate::FlagsInitialize(&api_flags);
flags = &api_flags;
}
Isolate* I = Dart::CreateIsolate(isolate_name, *flags);

View file

@ -47,8 +47,16 @@ R(dump_symbol_stats, false, bool, false, \
"Dump symbol table statistics") \
C(emit_edge_counters, false, true, bool, true, \
"Emit edge counters") \
R(enable_asserts, false, bool, false, \
"Enable assert statements.") \
C(enable_mirrors, false, false, bool, true, \
"Disable to make importing dart:mirrors an error.") \
R(enable_type_checks, false, bool, false, \
"Enable type checks.") \
R(error_on_bad_override, false, bool, false, \
"Report error for bad overrides.") \
R(error_on_bad_type, false, bool, false, \
"Report error for malformed types.") \
C(fields_may_be_reset, true, false, bool, false, \
"Don't optimize away static field initialization") \
R(gc_at_alloc, false, bool, false, \

View file

@ -993,7 +993,7 @@ BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
void TestGraphVisitor::ReturnValue(Value* value) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() || isolate->flags().asserts()) {
if (isolate->type_checks() || isolate->asserts()) {
value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
}
Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
@ -1028,7 +1028,7 @@ void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
false)); // No number check.
} else {
branch = new(Z) BranchInstr(comp);
branch->set_is_checked(Isolate::Current()->flags().type_checks());
branch->set_is_checked(Isolate::Current()->type_checks());
}
AddInstruction(branch);
CloseFragment();
@ -1038,7 +1038,7 @@ void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
ASSERT(!Isolate::Current()->flags().type_checks());
ASSERT(!Isolate::Current()->type_checks());
Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
StrictCompareInstr* comp =
new(Z) StrictCompareInstr(condition_token_pos(),
@ -1060,7 +1060,7 @@ void TestGraphVisitor::ReturnDefinition(Definition* definition) {
MergeBranchWithComparison(comp);
return;
}
if (!Isolate::Current()->flags().type_checks()) {
if (!Isolate::Current()->type_checks()) {
BooleanNegateInstr* neg = definition->AsBooleanNegate();
if (neg != NULL) {
MergeBranchWithNegate(neg);
@ -1153,7 +1153,7 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
return_value = Bind(BuildLoadLocal(*temp, node->token_pos()));
}
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
const bool is_implicit_dynamic_getter =
(!function.is_static() &&
((function.kind() == RawFunction::kImplicitGetter) ||
@ -1354,7 +1354,7 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
node->left()->Visit(&for_left);
EffectGraphVisitor empty(owner());
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() || isolate->flags().asserts()) {
if (isolate->type_checks() || isolate->asserts()) {
ValueGraphVisitor for_right(owner());
node->right()->Visit(&for_right);
Value* right_value = for_right.value();
@ -1421,7 +1421,7 @@ void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
node->right()->Visit(&for_right);
Value* right_value = for_right.value();
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() || isolate->flags().asserts()) {
if (isolate->type_checks() || isolate->asserts()) {
right_value =
for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
right_value));
@ -1800,7 +1800,7 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
owner()->ic_data_array());
if (node->kind() == Token::kNE) {
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() || isolate->flags().asserts()) {
if (isolate->type_checks() || isolate->asserts()) {
Value* value = Bind(result);
result = new(Z) AssertBooleanInstr(node->token_pos(), value);
}
@ -1847,7 +1847,7 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
Append(for_value);
Value* value = for_value.value();
Isolate* isolate = Isolate::Current();
if (isolate->flags().type_checks() || isolate->flags().asserts()) {
if (isolate->type_checks() || isolate->asserts()) {
value =
Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
}
@ -3642,7 +3642,7 @@ void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
node->value()->Visit(&for_value);
Append(for_value);
Value* store_value = for_value.value();
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
store_value = BuildAssignableValue(node->value()->token_pos(),
store_value,
node->local().type(),
@ -3686,7 +3686,7 @@ void EffectGraphVisitor::VisitStoreInstanceFieldNode(
node->value()->Visit(&for_value);
Append(for_value);
Value* store_value = for_value.value();
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
const AbstractType& type =
AbstractType::ZoneHandle(Z, node->field().type());
const String& dst_name = String::ZoneHandle(Z, node->field().name());
@ -4116,7 +4116,7 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
}
}
if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) {
if (Isolate::Current()->type_checks() && is_top_level_sequence) {
const int num_params = function.NumParameters();
int pos = 0;
if (function.IsFactory() ||

View file

@ -1090,7 +1090,7 @@ void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) {
bool FlowGraphCompiler::TryIntrinsify() {
// Intrinsification skips arguments checks, therefore disable if in checked
// mode.
if (FLAG_intrinsify && !isolate()->flags().type_checks()) {
if (FLAG_intrinsify && !isolate()->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

@ -2237,7 +2237,7 @@ static bool InlineSetIndexed(FlowGraph* flow_graph,
call->GetBlock()->try_index());
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
if (flow_graph->isolate()->flags().type_checks()) {
if (flow_graph->isolate()->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.

View file

@ -45,7 +45,7 @@ FlowGraphTypePropagator::FlowGraphTypePropagator(FlowGraph* flow_graph)
types_.Add(NULL);
}
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->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++) {
@ -127,7 +127,7 @@ void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
const intptr_t rollback_point = rollback_.length();
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
StrengthenAsserts(block);
}
@ -890,7 +890,7 @@ CompileType StaticCallInstr::ComputeType() const {
return CompileType::FromCid(result_cid_);
}
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
// Void functions are known to return null, which is checked at the return
// from the function.
const AbstractType& result_type =
@ -905,7 +905,7 @@ CompileType StaticCallInstr::ComputeType() const {
CompileType LoadLocalInstr::ComputeType() const {
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return CompileType::FromAbstractType(local().type());
}
return CompileType::Dynamic();
@ -949,7 +949,7 @@ CompileType LoadStaticFieldInstr::ComputeType() const {
intptr_t cid = kDynamicCid;
AbstractType* abstract_type = NULL;
const Field& field = this->StaticField();
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
cid = kIllegalCid;
abstract_type = &AbstractType::ZoneHandle(field.type());
}
@ -1008,7 +1008,7 @@ CompileType LoadFieldInstr::ComputeType() const {
}
const AbstractType* abstract_type = NULL;
if (Isolate::Current()->flags().type_checks() &&
if (Isolate::Current()->type_checks() &&
type().HasResolvedTypeClass() &&
!Field::IsExternalizableCid(Class::Handle(type().type_class()).id())) {
abstract_type = &type();

View file

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

View file

@ -373,13 +373,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
__ CompareObject(reg, Bool::True());
__ b(&done, EQ);
__ CompareObject(reg, Bool::False());
__ b(&done, EQ);
} else {
ASSERT(Isolate::Current()->flags().asserts());
ASSERT(Isolate::Current()->asserts());
__ CompareObject(reg, Object::null_instance());
__ b(&done, NE);
}

View file

@ -361,13 +361,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
__ CompareObject(reg, Bool::True());
__ b(&done, EQ);
__ CompareObject(reg, Bool::False());
__ b(&done, EQ);
} else {
ASSERT(Isolate::Current()->flags().asserts());
ASSERT(Isolate::Current()->asserts());
__ CompareObject(reg, Object::null_instance());
__ b(&done, NE);
}

View file

@ -247,13 +247,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
__ CompareObject(reg, Bool::True());
__ j(EQUAL, &done, Assembler::kNearJump);
__ CompareObject(reg, Bool::False());
__ j(EQUAL, &done, Assembler::kNearJump);
} else {
ASSERT(Isolate::Current()->flags().asserts());
ASSERT(Isolate::Current()->asserts());
__ CompareObject(reg, Object::null_instance());
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
}

View file

@ -422,11 +422,11 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
__ BranchEqual(reg, Bool::True(), &done);
__ BranchEqual(reg, Bool::False(), &done);
} else {
ASSERT(Isolate::Current()->flags().asserts());
ASSERT(Isolate::Current()->asserts());
__ BranchNotEqual(reg, Object::null_instance(), &done);
}

View file

@ -332,13 +332,13 @@ static void EmitAssertBoolean(Register reg,
ASSERT(locs->always_calls());
Label done;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
__ CompareObject(reg, Bool::True());
__ j(EQUAL, &done, Assembler::kNearJump);
__ CompareObject(reg, Bool::False());
__ j(EQUAL, &done, Assembler::kNearJump);
} else {
ASSERT(Isolate::Current()->flags().asserts());
ASSERT(Isolate::Current()->asserts());
__ CompareObject(reg, Object::null_instance());
__ j(NOT_EQUAL, &done, Assembler::kNearJump);
}

View file

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

View file

@ -35,7 +35,7 @@ intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
// Intrinsify only for Smi value and index. Non-smi values need a store buffer
// update. Array length is always a Smi.
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
@ -109,7 +109,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()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
Label fall_through;

View file

@ -34,7 +34,7 @@ intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
// Intrinsify only for Smi value and index. Non-smi values need a store buffer
// update. Array length is always a Smi.
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
@ -107,7 +107,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()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
Label fall_through;

View file

@ -55,7 +55,7 @@ static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
// update. Array length is always a Smi.
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
Label fall_through;
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
const intptr_t type_args_field_offset =
ComputeObjectArrayTypeArgumentsOffset();
// Inline simple tests (Smi, null), fallthrough if not positive.
@ -156,7 +156,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()->flags().type_checks()) return;
if (Isolate::Current()->type_checks()) return;
Label fall_through;
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.

View file

@ -34,7 +34,7 @@ intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
// Intrinsify only for Smi value and index. Non-smi values need a store buffer
// update. Array length is always a Smi.
void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
if (Isolate::Current()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
@ -106,7 +106,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()->flags().type_checks()) return;
if (Isolate::Current()->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()->flags().type_checks()) {
if (Isolate::Current()->type_checks()) {
return;
}
@ -102,7 +102,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()->flags().type_checks()) return;
if (Isolate::Current()->type_checks()) return;
Label fall_through;
__ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
__ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));

View file

@ -77,18 +77,9 @@ DEFINE_FLAG(int, external_max_size, (kWordSize <= 4) ? 512 : 1024,
"Max total size of external allocations in MB, or 0 for unlimited,"
"e.g: --external_max_size=1024 allows up to 1024MB of externals");
// 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.");
DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
NOT_IN_PRODUCT(
static void CheckedModeHandler(bool value) {
FLAG_enable_asserts = value;
FLAG_enable_type_checks = value;
@ -103,6 +94,7 @@ DEFINE_FLAG_HANDLER(CheckedModeHandler,
DEFINE_FLAG_HANDLER(CheckedModeHandler,
checked,
"Enable checked mode.");
)
// Quick access to the locally defined thread() and isolate() methods.
@ -712,31 +704,16 @@ MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
}
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::FlagsInitialize(Dart_IsolateFlags* api_flags) {
api_flags->version = DART_FLAGS_CURRENT_VERSION;
api_flags->enable_type_checks = FLAG_enable_type_checks;
api_flags->enable_asserts = FLAG_enable_asserts;
api_flags->enable_error_on_bad_type = FLAG_error_on_bad_type;
api_flags->enable_error_on_bad_override = FLAG_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;
error_on_bad_type_ = api_flags.enable_error_on_bad_type;
error_on_bad_override_ = api_flags.enable_error_on_bad_override;
// Leave others at defaults.
}
void Isolate::Flags::CopyTo(Dart_IsolateFlags* api_flags) const {
void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
api_flags->version = DART_FLAGS_CURRENT_VERSION;
api_flags->enable_type_checks = type_checks();
api_flags->enable_asserts = asserts();
@ -745,7 +722,17 @@ void Isolate::Flags::CopyTo(Dart_IsolateFlags* api_flags) const {
}
#if defined(DEBUG)
NOT_IN_PRODUCT(
void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
type_checks_ = api_flags.enable_type_checks;
asserts_ = api_flags.enable_asserts;
error_on_bad_type_ = api_flags.enable_error_on_bad_type;
error_on_bad_override_ = api_flags.enable_error_on_bad_override;
// Leave others at defaults.
})
DEBUG_ONLY(
// static
void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
ASSERT(isolate == Isolate::Current());
@ -755,7 +742,7 @@ void BaseIsolate::AssertCurrentThreadIsMutator() const {
ASSERT(Isolate::Current() == this);
ASSERT(Thread::Current()->IsMutatorThread());
}
#endif // defined(DEBUG)
)
#if defined(DEBUG)
#define REUSABLE_HANDLE_SCOPE_INIT(object) \
@ -799,7 +786,6 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
resume_request_(false),
last_resume_timestamp_(OS::GetCurrentTimeMillis()),
has_compiled_code_(false),
flags_(),
random_(),
simulator_(NULL),
mutex_(new Mutex()),
@ -840,7 +826,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
boxed_field_list_(GrowableObjectArray::null()),
spawn_count_monitor_(new Monitor()),
spawn_count_(0) {
flags_.CopyFrom(api_flags);
NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
// TODO(asiva): A Thread is not available here, need to figure out
// how the vm_tag (kEmbedderTagId) can be set, these tags need to
// move to the OSThread structure.
@ -2656,7 +2642,6 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
serialized_message_len_(0),
spawn_count_monitor_(spawn_count_monitor),
spawn_count_(spawn_count),
isolate_flags_(),
paused_(paused),
errors_are_fatal_(errors_are_fatal) {
const Class& cls = Class::Handle(func.Owner());
@ -2676,7 +2661,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
&serialized_message_len_,
can_send_any_object);
// Inherit flags from spawning isolate.
isolate_flags()->CopyFrom(Isolate::Current()->flags());
Isolate::Current()->FlagsCopyTo(isolate_flags());
}
@ -2726,7 +2711,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
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());
Isolate::Current()->FlagsCopyTo(isolate_flags());
}

View file

@ -337,42 +337,6 @@ class Isolate : public BaseIsolate {
void set_has_compiled_code(bool value) { has_compiled_code_ = value; }
bool has_compiled_code() const { return has_compiled_code_; }
// 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_; }
// Lets the embedder know that a service message resulted in a resume request.
void SetResumeRequest() {
resume_request_ = true;
@ -672,6 +636,23 @@ class Isolate : public BaseIsolate {
bool is_service_isolate() const { return is_service_isolate_; }
// Isolate-specific flag handling.
static void FlagsInitialize(Dart_IsolateFlags* api_flags);
void FlagsCopyTo(Dart_IsolateFlags* api_flags) const;
void FlagsCopyFrom(const Dart_IsolateFlags& api_flags);
#if defined(PRODUCT)
bool type_checks() const { return FLAG_enable_type_checks; }
bool asserts() const { return FLAG_enable_asserts; }
bool error_on_bad_type() const { return FLAG_error_on_bad_type; }
bool error_on_bad_override() const { return FLAG_error_on_bad_override; }
#else // defined(PRODUCT)
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_; }
#endif // defined(PRODUCT)
static void KillAllIsolates(LibMsgId msg_id);
static void KillIfExists(Isolate* isolate, LibMsgId msg_id);
@ -769,7 +750,6 @@ class Isolate : public BaseIsolate {
bool resume_request_;
int64_t last_resume_timestamp_;
bool has_compiled_code_; // Can check that no compilation occured.
Flags flags_;
Random random_;
Simulator* simulator_;
Mutex* mutex_; // protects stack_limit_, saved_stack_limit_, compiler stats.
@ -791,6 +771,14 @@ class Isolate : public BaseIsolate {
bool is_service_isolate_;
// Isolate-specific flags.
NOT_IN_PRODUCT(
bool type_checks_;
bool asserts_;
bool error_on_bad_type_;
bool error_on_bad_override_;
)
// Status support.
char* stacktrace_;
intptr_t stack_frame_index_;
@ -997,7 +985,7 @@ class IsolateSpawnState {
bool is_spawn_uri() const { return library_url_ == NULL; }
bool paused() const { return paused_; }
bool errors_are_fatal() const { return errors_are_fatal_; }
Isolate::Flags* isolate_flags() { return &isolate_flags_; }
Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
RawObject* ResolveFunction();
RawInstance* BuildArgs(Thread* thread);
@ -1028,7 +1016,7 @@ class IsolateSpawnState {
Monitor* spawn_count_monitor_;
intptr_t* spawn_count_;
Isolate::Flags isolate_flags_;
Dart_IsolateFlags isolate_flags_;
bool paused_;
bool errors_are_fatal_;
};

View file

@ -3081,7 +3081,7 @@ bool JitOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
const ICData& unary_ic_data) {
ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
(unary_ic_data.NumArgsTested() == 1));
if (I->flags().type_checks()) {
if (I->type_checks()) {
// Checked mode setters are inlined like normal methods by conventional
// inlining.
return false;

View file

@ -5942,7 +5942,7 @@ const char* Function::ToQualifiedCString() const {
bool Function::HasCompatibleParametersWith(const Function& other,
Error* bound_error) const {
ASSERT(Isolate::Current()->flags().error_on_bad_override());
ASSERT(Isolate::Current()->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.
@ -14236,7 +14236,7 @@ bool Instance::IsInstanceOf(const AbstractType& other,
zone, other.InstantiateFrom(other_instantiator, bound_error,
NULL, NULL, Heap::kOld));
if ((bound_error != NULL) && !bound_error->IsNull()) {
ASSERT(Isolate::Current()->flags().type_checks());
ASSERT(Isolate::Current()->type_checks());
return false;
}
if (instantiated_other.IsTypeRef()) {
@ -14292,7 +14292,7 @@ bool Instance::IsInstanceOf(const AbstractType& other,
instantiated_other = other.InstantiateFrom(other_instantiator, bound_error,
NULL, NULL, Heap::kOld);
if ((bound_error != NULL) && !bound_error->IsNull()) {
ASSERT(Isolate::Current()->flags().type_checks());
ASSERT(Isolate::Current()->type_checks());
return false;
}
if (instantiated_other.IsTypeRef()) {
@ -14985,14 +14985,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()->flags().type_checks());
ASSERT(Isolate::Current()->type_checks());
if ((bound_error != NULL) && bound_error->IsNull()) {
*bound_error = error();
}
return false;
}
if (other.IsMalbounded()) {
ASSERT(Isolate::Current()->flags().type_checks());
ASSERT(Isolate::Current()->type_checks());
if ((bound_error != NULL) && bound_error->IsNull()) {
*bound_error = other.error();
}
@ -15243,7 +15243,7 @@ bool Type::IsMalformed() const {
bool Type::IsMalbounded() const {
if (!Isolate::Current()->flags().type_checks()) {
if (!Isolate::Current()->type_checks()) {
return false;
}
if (raw_ptr()->error_ == LanguageError::null()) {
@ -15263,7 +15263,7 @@ bool Type::IsMalformedOrMalbounded() const {
return true;
}
ASSERT(type_error.kind() == Report::kMalboundedType);
return Isolate::Current()->flags().type_checks();
return Isolate::Current()->type_checks();
}
@ -15750,7 +15750,7 @@ bool FunctionType::IsMalformed() const {
bool FunctionType::IsMalbounded() const {
if (!Isolate::Current()->flags().type_checks()) {
if (!Isolate::Current()->type_checks()) {
return false;
}
if (raw_ptr()->error_ == LanguageError::null()) {
@ -15770,7 +15770,7 @@ bool FunctionType::IsMalformedOrMalbounded() const {
return true;
}
ASSERT(type_error.kind() == Report::kMalboundedType);
return Isolate::Current()->flags().type_checks();
return Isolate::Current()->type_checks();
}
@ -16713,7 +16713,7 @@ RawAbstractType* BoundedType::InstantiateFrom(
// (or instantiated) either.
// Note that instantiator_type_arguments must have the final length, though.
}
if ((Isolate::Current()->flags().type_checks()) &&
if ((Isolate::Current()->type_checks()) &&
(bound_error != NULL) && bound_error->IsNull()) {
AbstractType& upper_bound = AbstractType::Handle(bound());
ASSERT(upper_bound.IsFinalized());

View file

@ -3274,7 +3274,7 @@ SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) {
// Populate function scope with the formal parameters.
AddFormalParamsToScope(&params, current_block_->scope);
if (I->flags().type_checks() &&
if (I->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.
@ -7462,7 +7462,7 @@ AstNode* Parser::ParseVariableDeclarationList() {
bool is_final = (CurrentToken() == Token::kFINAL);
bool is_const = (CurrentToken() == Token::kCONST);
const AbstractType& type = AbstractType::ZoneHandle(Z,
ParseConstFinalVarOrType(I->flags().type_checks() ?
ParseConstFinalVarOrType(I->type_checks() ?
ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore));
if (!IsIdentifier()) {
ReportError("identifier expected");
@ -8530,7 +8530,7 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
// position, which is inside the loop body.
new_loop_var = true;
loop_var_type = ParseConstFinalVarOrType(
I->flags().type_checks() ? ClassFinalizer::kCanonicalize :
I->type_checks() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
}
TokenPosition loop_var_pos = TokenPos();
@ -8824,7 +8824,7 @@ AstNode* Parser::ParseForInStatement(TokenPosition forin_pos,
// position, which is inside the loop body.
new_loop_var = true;
loop_var_type = ParseConstFinalVarOrType(
I->flags().type_checks() ? ClassFinalizer::kCanonicalize :
I->type_checks() ? ClassFinalizer::kCanonicalize :
ClassFinalizer::kIgnore);
loop_var_name = ExpectIdentifier("variable name expected");
}
@ -9043,7 +9043,7 @@ AstNode* Parser::ParseAssertStatement() {
ConsumeToken(); // Consume assert keyword.
ExpectToken(Token::kLPAREN);
const TokenPosition condition_pos = TokenPos();
if (!I->flags().asserts()) {
if (!I->asserts()) {
SkipExpr();
ExpectToken(Token::kRPAREN);
return NULL;
@ -12650,7 +12650,7 @@ AstNode* Parser::ParseListLiteral(TokenPosition type_pos,
"include a type variable");
}
} else {
if (I->flags().error_on_bad_type()) {
if (I->error_on_bad_type()) {
ReportError(type_pos,
"a list literal takes one type argument specifying "
"the element type");
@ -12673,7 +12673,7 @@ AstNode* Parser::ParseListLiteral(TokenPosition type_pos,
while (CurrentToken() != Token::kRBRACK) {
const TokenPosition element_pos = TokenPos();
AstNode* element = ParseExpr(is_const, kConsumeCascades);
if (I->flags().type_checks() &&
if (I->type_checks() &&
!is_const &&
!element_type.IsDynamicType()) {
element = new(Z) AssignableNode(element_pos,
@ -12704,7 +12704,7 @@ AstNode* Parser::ParseListLiteral(TokenPosition 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->flags().type_checks() &&
if (I->type_checks() &&
!element_type.IsDynamicType() &&
(!elem->AsLiteralNode()->literal().IsNull() &&
!elem->AsLiteralNode()->literal().IsInstanceOf(
@ -12856,7 +12856,7 @@ AstNode* Parser::ParseMapLiteral(TokenPosition type_pos,
"include a type variable");
}
} else {
if (I->flags().error_on_bad_type()) {
if (I->error_on_bad_type()) {
ReportError(type_pos,
"a map literal takes two type arguments specifying "
"the key type and the value type");
@ -12875,7 +12875,7 @@ AstNode* Parser::ParseMapLiteral(TokenPosition type_pos,
const bool saved_mode = SetAllowFunctionLiterals(true);
const TokenPosition key_pos = TokenPos();
AstNode* key = ParseExpr(is_const, kConsumeCascades);
if (I->flags().type_checks() &&
if (I->type_checks() &&
!is_const &&
!key_type.IsDynamicType()) {
key = new(Z) AssignableNode(
@ -12898,7 +12898,7 @@ AstNode* Parser::ParseMapLiteral(TokenPosition type_pos,
const TokenPosition value_pos = TokenPos();
AstNode* value = ParseExpr(is_const, kConsumeCascades);
SetAllowFunctionLiterals(saved_mode);
if (I->flags().type_checks() &&
if (I->type_checks() &&
!is_const &&
!value_type.IsDynamicType()) {
value = new(Z) AssignableNode(
@ -12930,7 +12930,7 @@ AstNode* Parser::ParseMapLiteral(TokenPosition 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->flags().type_checks()) {
if (I->type_checks()) {
if ((i % 2) == 0) {
// Check key type.
arg_type = key_type.raw();
@ -13432,7 +13432,7 @@ AstNode* Parser::ParseNewOperator(Token::Kind op_kind) {
}
return ThrowTypeError(redirect_type.token_pos(), redirect_type);
}
if (I->flags().type_checks() &&
if (I->type_checks() &&
!redirect_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
// Additional type checking of the result is necessary.
type_bound = type.raw();

View file

@ -320,9 +320,8 @@ class RunServiceTask : public ThreadPool::Task {
return;
}
Isolate::Flags default_flags;
Dart_IsolateFlags api_flags;
default_flags.CopyTo(&api_flags);
Isolate::FlagsInitialize(&api_flags);
isolate =
reinterpret_cast<Isolate*>(create_callback(ServiceIsolate::kName,

View file

@ -18,7 +18,6 @@
namespace dart {
DECLARE_FLAG(bool, enable_type_checks);
DECLARE_FLAG(bool, concurrent_sweep);
// Check if serialized and deserialized objects are equal.
@ -1579,7 +1578,7 @@ UNIT_TEST_CASE(ScriptSnapshot2) {
// Force creation of snapshot in production mode.
bool saved_enable_type_checks_mode = FLAG_enable_type_checks;
FLAG_enable_type_checks = false;
NOT_IN_PRODUCT(FLAG_enable_type_checks = false);
bool saved_load_deferred_eagerly_mode = FLAG_load_deferred_eagerly;
FLAG_load_deferred_eagerly = true;
bool saved_concurrent_sweep_mode = FLAG_concurrent_sweep;
@ -1631,7 +1630,7 @@ UNIT_TEST_CASE(ScriptSnapshot2) {
}
// Continue in originally saved mode.
FLAG_enable_type_checks = saved_enable_type_checks_mode;
NOT_IN_PRODUCT(FLAG_enable_type_checks = saved_enable_type_checks_mode);
FLAG_load_deferred_eagerly = saved_load_deferred_eagerly_mode;
{