Use zone when allocating handles in FlowGraphCompiler assembling operations. Add profiling VM tags for parse and flow graph builder, active only when --profile_vm. Lazily generate IR constant_value handles.
BUG= R=regis@google.com Review URL: https://codereview.chromium.org//1263573010 .
This commit is contained in:
@@ -735,7 +735,7 @@ void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) {
|
||||
|
||||
|
||||
void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) {
|
||||
const Definition* def = instr->value()->definition();
|
||||
Definition* def = instr->value()->definition();
|
||||
const Object& value = def->constant_value();
|
||||
if (IsNonConstant(value)) {
|
||||
const AbstractType& checked_type = instr->type();
|
||||
|
||||
@@ -42,6 +42,7 @@ DEFINE_FLAG(bool, precompile_collect_closures, false,
|
||||
"Collect all closure functions referenced from compiled code.");
|
||||
|
||||
DECLARE_FLAG(int, optimization_counter_threshold);
|
||||
DECLARE_FLAG(bool, profile_vm);
|
||||
DECLARE_FLAG(bool, warn_on_javascript_compatibility);
|
||||
DECLARE_FLAG(bool, use_field_guards);
|
||||
|
||||
@@ -4783,6 +4784,9 @@ void EffectGraphVisitor::VisitStopNode(StopNode* node) {
|
||||
|
||||
|
||||
FlowGraph* FlowGraphBuilder::BuildGraph() {
|
||||
VMTagScope tagScope(Thread::Current()->isolate(),
|
||||
VMTag::kCompileFlowGraphBuilderTagId,
|
||||
FLAG_profile_vm);
|
||||
if (FLAG_print_ast) {
|
||||
// Print the function ast before IL generation.
|
||||
AstPrinter::PrintFunctionNodes(parsed_function());
|
||||
|
||||
@@ -98,15 +98,17 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// The real frame starts here.
|
||||
builder->MarkFrameStart();
|
||||
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
|
||||
// Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
|
||||
builder->AddPcMarker(Function::Handle(), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
|
||||
// Emit all values that are needed for materialization as a part of the
|
||||
// expression stack for the bottom-most frame. This guarantees that GC
|
||||
@@ -124,17 +126,19 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPp(
|
||||
Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
@@ -167,7 +171,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
|
||||
// For the outermost environment, set the incoming arguments.
|
||||
@@ -233,7 +237,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
|
||||
ASSERT(instance_reg == R0);
|
||||
ASSERT(temp_reg == kNoRegister); // Unused on ARM.
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
|
||||
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
|
||||
__ LoadUniqueObject(R2, type_test_cache);
|
||||
if (test_kind == kTestTypeOneArg) {
|
||||
ASSERT(type_arguments_reg == kNoRegister);
|
||||
@@ -268,11 +272,11 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeWithArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
|
||||
const Register kInstanceReg = R0;
|
||||
Error& malformed_error = Error::Handle();
|
||||
const Type& int_type = Type::Handle(Type::IntType());
|
||||
Error& malformed_error = Error::Handle(zone());
|
||||
const Type& int_type = Type::Handle(zone(), Type::IntType());
|
||||
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
|
||||
// Malformed type should have been handled at graph construction time.
|
||||
ASSERT(smi_is_ok || malformed_error.IsNull());
|
||||
@@ -286,7 +290,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
const intptr_t num_type_params = type_class.NumTypeParameters();
|
||||
const intptr_t from_index = num_type_args - num_type_params;
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::ZoneHandle(type.arguments());
|
||||
TypeArguments::ZoneHandle(zone(), type.arguments());
|
||||
const bool is_raw_type = type_arguments.IsNull() ||
|
||||
type_arguments.IsRaw(from_index, num_type_params);
|
||||
// Signature class is an instantiated parameterized type.
|
||||
@@ -307,12 +311,12 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
// If one type argument only, check if type argument is Object or dynamic.
|
||||
if (type_arguments.Length() == 1) {
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(
|
||||
type_arguments.TypeAt(0));
|
||||
zone(), type_arguments.TypeAt(0));
|
||||
ASSERT(!tp_argument.IsMalformed());
|
||||
if (tp_argument.IsType()) {
|
||||
ASSERT(tp_argument.HasResolvedTypeClass());
|
||||
// Check if type argument is dynamic or Object.
|
||||
const Type& object_type = Type::Handle(Type::ObjectType());
|
||||
const Type& object_type = Type::Handle(zone(), Type::ObjectType());
|
||||
if (object_type.IsSubtypeOf(tp_argument, NULL)) {
|
||||
// Instance class test only necessary.
|
||||
return GenerateSubtype1TestCacheLookup(
|
||||
@@ -358,16 +362,16 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeNoArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
const Class& type_class = Class::Handle(zone(), type.type_class());
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
|
||||
const Register kInstanceReg = R0;
|
||||
__ tst(kInstanceReg, Operand(kSmiTagMask));
|
||||
// If instance is Smi, check directly.
|
||||
const Class& smi_class = Class::Handle(Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
|
||||
const Class& smi_class = Class::Handle(zone(), Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
|
||||
type_class,
|
||||
TypeArguments::Handle(),
|
||||
TypeArguments::Handle(zone()),
|
||||
NULL)) {
|
||||
__ b(is_instance_lbl, EQ);
|
||||
} else {
|
||||
@@ -396,7 +400,7 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
}
|
||||
// Custom checking for numbers (Smi, Mint, Bigint and Double).
|
||||
// Note that instance is not Smi (checked above).
|
||||
if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
|
||||
if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
|
||||
GenerateNumberTypeCheck(
|
||||
kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
|
||||
return false;
|
||||
@@ -465,18 +469,18 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
|
||||
// R2: concrete type of type.
|
||||
// Check if type argument is dynamic.
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::DynamicType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::ObjectType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
|
||||
// For Smi check quickly against int and num interfaces.
|
||||
Label not_smi;
|
||||
__ tst(R0, Operand(kSmiTagMask)); // Value is Smi?
|
||||
__ b(¬_smi, NE);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::IntType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::IntType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::Number()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::Number()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
// Smi must be handled in runtime.
|
||||
Label fall_through;
|
||||
@@ -489,7 +493,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
const Register kTypeArgumentsReg = R1;
|
||||
const Register kTempReg = kNoRegister;
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(
|
||||
SubtypeTestCache::ZoneHandle(zone(),
|
||||
GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
|
||||
kInstanceReg,
|
||||
kTypeArgumentsReg,
|
||||
@@ -540,7 +544,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
|
||||
return SubtypeTestCache::null();
|
||||
}
|
||||
if (type.IsInstantiated()) {
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
// A class equality check is only applicable with a dst type of a
|
||||
// non-parameterized class, non-signature class, or with a raw dst type of
|
||||
// a parameterized class.
|
||||
@@ -609,7 +613,7 @@ void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline instanceof test.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, type,
|
||||
&is_instance, &is_not_instance);
|
||||
|
||||
@@ -704,7 +708,7 @@ void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline type check, linking to runtime call if not assignable.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, dst_type,
|
||||
&is_assignable, &runtime_call);
|
||||
|
||||
@@ -861,7 +865,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ Bind(&load_default_value);
|
||||
// Load R5 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
parsed_function().default_parameter_values().At(
|
||||
zone(), parsed_function().default_parameter_values().At(
|
||||
param_pos - num_fixed_params));
|
||||
__ LoadObject(R5, value);
|
||||
__ Bind(&assign_optional_parameter);
|
||||
@@ -897,7 +901,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ b(&next_parameter, GT);
|
||||
// Load R5 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
parsed_function().default_parameter_values().At(i));
|
||||
zone(), parsed_function().default_parameter_values().At(i));
|
||||
__ LoadObject(R5, value);
|
||||
// Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
|
||||
// We do not use the final allocation index of the variable here, i.e.
|
||||
@@ -1208,8 +1212,8 @@ void FlowGraphCompiler::EmitEdgeCounter() {
|
||||
// deoptimize, there is a bound on the number of
|
||||
// optimization/deoptimization cycles we will attempt.
|
||||
ASSERT(assembler_->constant_pool_allowed());
|
||||
const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(Smi::New(0)));
|
||||
const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
|
||||
__ Comment("Edge counter");
|
||||
__ LoadUniqueObject(R0, counter);
|
||||
intptr_t increment_start = assembler_->CodeSize();
|
||||
@@ -1246,7 +1250,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
// Each ICData propagated from unoptimized to optimized code contains the
|
||||
// function that corresponds to the Dart function of that IC call. Due
|
||||
// to inlining in optimized code, that function may not correspond to the
|
||||
@@ -1271,7 +1275,7 @@ void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
__ LoadUniqueObject(R5, ic_data);
|
||||
GenerateDartCall(deopt_id,
|
||||
token_pos,
|
||||
@@ -1289,12 +1293,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ic_data.arguments_descriptor());
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = R0;
|
||||
const Register cacheR = R1;
|
||||
const Register targetR = R1;
|
||||
@@ -1524,8 +1528,8 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
ASSERT(is_optimizing());
|
||||
__ Comment("EmitTestAndCall");
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
|
||||
// Load receiver into R0.
|
||||
__ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
|
||||
@@ -1552,7 +1556,7 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
&StubCode::CallStaticFunctionLabel(),
|
||||
RawPcDescriptors::kOther,
|
||||
locs);
|
||||
const Function& function = Function::Handle(ic_data.GetTargetAt(0));
|
||||
const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
|
||||
AddStaticCallTarget(function);
|
||||
__ Drop(argument_count);
|
||||
if (kNumChecks > 1) {
|
||||
|
||||
@@ -95,11 +95,13 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// The real frame starts here.
|
||||
builder->MarkFrameStart();
|
||||
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(), slot_ix++);
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
|
||||
@@ -119,16 +121,18 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPp(Function::Handle(
|
||||
zone, current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
// we must read them from the previous environment.
|
||||
@@ -157,7 +161,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// For the outermost environment, set caller PC, caller PP, and caller FP.
|
||||
builder->AddCallerPp(slot_ix++);
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
@@ -220,7 +224,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
|
||||
ASSERT(instance_reg == R0);
|
||||
ASSERT(temp_reg == kNoRegister); // Unused on ARM.
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
|
||||
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
|
||||
__ LoadUniqueObject(R2, type_test_cache);
|
||||
if (test_kind == kTestTypeOneArg) {
|
||||
ASSERT(type_arguments_reg == kNoRegister);
|
||||
@@ -255,11 +259,11 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeWithArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
|
||||
const Register kInstanceReg = R0;
|
||||
Error& malformed_error = Error::Handle();
|
||||
const Type& int_type = Type::Handle(Type::IntType());
|
||||
Error& malformed_error = Error::Handle(zone());
|
||||
const Type& int_type = Type::Handle(zone(), Type::IntType());
|
||||
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
|
||||
// Malformed type should have been handled at graph construction time.
|
||||
ASSERT(smi_is_ok || malformed_error.IsNull());
|
||||
@@ -273,7 +277,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
const intptr_t num_type_params = type_class.NumTypeParameters();
|
||||
const intptr_t from_index = num_type_args - num_type_params;
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::ZoneHandle(type.arguments());
|
||||
TypeArguments::ZoneHandle(zone(), type.arguments());
|
||||
const bool is_raw_type = type_arguments.IsNull() ||
|
||||
type_arguments.IsRaw(from_index, num_type_params);
|
||||
// Signature class is an instantiated parameterized type.
|
||||
@@ -294,12 +298,12 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
// If one type argument only, check if type argument is Object or dynamic.
|
||||
if (type_arguments.Length() == 1) {
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(
|
||||
type_arguments.TypeAt(0));
|
||||
zone(), type_arguments.TypeAt(0));
|
||||
ASSERT(!tp_argument.IsMalformed());
|
||||
if (tp_argument.IsType()) {
|
||||
ASSERT(tp_argument.HasResolvedTypeClass());
|
||||
// Check if type argument is dynamic or Object.
|
||||
const Type& object_type = Type::Handle(Type::ObjectType());
|
||||
const Type& object_type = Type::Handle(zone(), Type::ObjectType());
|
||||
if (object_type.IsSubtypeOf(tp_argument, NULL)) {
|
||||
// Instance class test only necessary.
|
||||
return GenerateSubtype1TestCacheLookup(
|
||||
@@ -345,16 +349,16 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeNoArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
const Class& type_class = Class::Handle(zone(), type.type_class());
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
|
||||
const Register kInstanceReg = R0;
|
||||
__ tsti(kInstanceReg, Immediate(kSmiTagMask));
|
||||
// If instance is Smi, check directly.
|
||||
const Class& smi_class = Class::Handle(Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
|
||||
const Class& smi_class = Class::Handle(zone(), Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
|
||||
type_class,
|
||||
TypeArguments::Handle(),
|
||||
TypeArguments::Handle(zone()),
|
||||
NULL)) {
|
||||
__ b(is_instance_lbl, EQ);
|
||||
} else {
|
||||
@@ -383,7 +387,7 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
}
|
||||
// Custom checking for numbers (Smi, Mint, Bigint and Double).
|
||||
// Note that instance is not Smi (checked above).
|
||||
if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
|
||||
if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
|
||||
GenerateNumberTypeCheck(
|
||||
kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
|
||||
return false;
|
||||
@@ -452,18 +456,18 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
R2, R1, TypeArguments::type_at_offset(type_param.index()));
|
||||
// R2: concrete type of type.
|
||||
// Check if type argument is dynamic.
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::DynamicType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::ObjectType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
|
||||
// For Smi check quickly against int and num interfaces.
|
||||
Label not_smi;
|
||||
__ tsti(R0, Immediate(kSmiTagMask)); // Value is Smi?
|
||||
__ b(¬_smi, NE);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::IntType()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::IntType()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
__ CompareObject(R2, Type::ZoneHandle(Type::Number()));
|
||||
__ CompareObject(R2, Type::ZoneHandle(zone(), Type::Number()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
// Smi must be handled in runtime.
|
||||
Label fall_through;
|
||||
@@ -476,7 +480,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
const Register kTypeArgumentsReg = R1;
|
||||
const Register kTempReg = kNoRegister;
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(
|
||||
SubtypeTestCache::ZoneHandle(zone(),
|
||||
GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
|
||||
kInstanceReg,
|
||||
kTypeArgumentsReg,
|
||||
@@ -527,7 +531,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
|
||||
return SubtypeTestCache::null();
|
||||
}
|
||||
if (type.IsInstantiated()) {
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
// A class equality check is only applicable with a dst type of a
|
||||
// non-parameterized class, non-signature class, or with a raw dst type of
|
||||
// a parameterized class.
|
||||
@@ -597,7 +601,7 @@ void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline instanceof test.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, type,
|
||||
&is_instance, &is_not_instance);
|
||||
|
||||
@@ -696,7 +700,7 @@ void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline type check, linking to runtime call if not assignable.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, dst_type,
|
||||
&is_assignable, &runtime_call);
|
||||
|
||||
@@ -858,7 +862,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ Bind(&load_default_value);
|
||||
// Load R5 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
parsed_function().default_parameter_values().At(
|
||||
zone(), parsed_function().default_parameter_values().At(
|
||||
param_pos - num_fixed_params));
|
||||
__ LoadObject(R5, value);
|
||||
__ Bind(&assign_optional_parameter);
|
||||
@@ -893,7 +897,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ b(&next_parameter, GT);
|
||||
// Load R5 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
parsed_function().default_parameter_values().At(i));
|
||||
zone(), parsed_function().default_parameter_values().At(i));
|
||||
__ LoadObject(R5, value);
|
||||
// Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
|
||||
// We do not use the final allocation index of the variable here, i.e.
|
||||
@@ -1201,8 +1205,8 @@ void FlowGraphCompiler::EmitEdgeCounter() {
|
||||
// deoptimize, there is a bound on the number of
|
||||
// optimization/deoptimization cycles we will attempt.
|
||||
ASSERT(assembler_->constant_pool_allowed());
|
||||
const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(Smi::New(0)));
|
||||
const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
|
||||
__ Comment("Edge counter");
|
||||
__ LoadUniqueObject(R0, counter);
|
||||
__ LoadFieldFromOffset(TMP, R0, Array::element_offset(0));
|
||||
@@ -1218,7 +1222,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
// Each ICData propagated from unoptimized to optimized code contains the
|
||||
// function that corresponds to the Dart function of that IC call. Due
|
||||
// to inlining in optimized code, that function may not correspond to the
|
||||
@@ -1243,7 +1247,7 @@ void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
__ LoadUniqueObject(R5, ic_data);
|
||||
GenerateDartCall(deopt_id,
|
||||
token_pos,
|
||||
@@ -1261,12 +1265,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ic_data.arguments_descriptor());
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = R0;
|
||||
const Register cacheR = R1;
|
||||
const Register targetR = R1;
|
||||
@@ -1479,8 +1483,8 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
|
||||
__ Comment("EmitTestAndCall");
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
|
||||
// Load receiver into R0.
|
||||
__ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
|
||||
@@ -1507,7 +1511,7 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
&StubCode::CallStaticFunctionLabel(),
|
||||
RawPcDescriptors::kOther,
|
||||
locs);
|
||||
const Function& function = Function::Handle(ic_data.GetTargetAt(0));
|
||||
const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
|
||||
AddStaticCallTarget(function);
|
||||
__ Drop(argument_count);
|
||||
if (kNumChecks > 1) {
|
||||
|
||||
@@ -100,12 +100,14 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// The real frame starts here.
|
||||
builder->MarkFrameStart();
|
||||
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
|
||||
builder->AddPcMarker(Function::Handle(), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
|
||||
// Current FP and PC.
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
|
||||
@@ -122,7 +124,8 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
}
|
||||
|
||||
// Current PC marker and caller FP.
|
||||
builder->AddPcMarker(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(
|
||||
zone, current->code().function()), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
Environment* previous = current;
|
||||
@@ -130,9 +133,10 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
while (current != NULL) {
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
// we must read them from the previous environment.
|
||||
@@ -152,7 +156,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
}
|
||||
|
||||
// PC marker and caller FP.
|
||||
builder->AddPcMarker(Function::Handle(current->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, current->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
@@ -224,7 +228,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
|
||||
Label* is_instance_lbl,
|
||||
Label* is_not_instance_lbl) {
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
|
||||
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
|
||||
const Immediate& raw_null =
|
||||
Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
||||
__ LoadObject(temp_reg, type_test_cache);
|
||||
@@ -268,11 +272,11 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeWithArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
|
||||
const Register kInstanceReg = EAX;
|
||||
Error& malformed_error = Error::Handle();
|
||||
const Type& int_type = Type::Handle(Type::IntType());
|
||||
Error& malformed_error = Error::Handle(zone());
|
||||
const Type& int_type = Type::Handle(zone(), Type::IntType());
|
||||
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
|
||||
// Malformed type should have been handled at graph construction time.
|
||||
ASSERT(smi_is_ok || malformed_error.IsNull());
|
||||
@@ -286,7 +290,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
const intptr_t num_type_params = type_class.NumTypeParameters();
|
||||
const intptr_t from_index = num_type_args - num_type_params;
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::ZoneHandle(type.arguments());
|
||||
TypeArguments::ZoneHandle(zone(), type.arguments());
|
||||
const bool is_raw_type = type_arguments.IsNull() ||
|
||||
type_arguments.IsRaw(from_index, num_type_params);
|
||||
// Signature class is an instantiated parameterized type.
|
||||
@@ -307,12 +311,12 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
// If one type argument only, check if type argument is Object or dynamic.
|
||||
if (type_arguments.Length() == 1) {
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(
|
||||
type_arguments.TypeAt(0));
|
||||
zone(), type_arguments.TypeAt(0));
|
||||
ASSERT(!tp_argument.IsMalformed());
|
||||
if (tp_argument.IsType()) {
|
||||
ASSERT(tp_argument.HasResolvedTypeClass());
|
||||
// Check if type argument is dynamic or Object.
|
||||
const Type& object_type = Type::Handle(Type::ObjectType());
|
||||
const Type& object_type = Type::Handle(zone(), Type::ObjectType());
|
||||
if (object_type.IsSubtypeOf(tp_argument, NULL)) {
|
||||
// Instance class test only necessary.
|
||||
return GenerateSubtype1TestCacheLookup(
|
||||
@@ -357,16 +361,16 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeNoArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
const Class& type_class = Class::Handle(zone(), type.type_class());
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
|
||||
const Register kInstanceReg = EAX;
|
||||
__ testl(kInstanceReg, Immediate(kSmiTagMask));
|
||||
// If instance is Smi, check directly.
|
||||
const Class& smi_class = Class::Handle(Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
|
||||
const Class& smi_class = Class::Handle(zone(), Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
|
||||
type_class,
|
||||
TypeArguments::Handle(),
|
||||
TypeArguments::Handle(zone()),
|
||||
NULL)) {
|
||||
__ j(ZERO, is_instance_lbl);
|
||||
} else {
|
||||
@@ -397,7 +401,7 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
}
|
||||
// Custom checking for numbers (Smi, Mint, Bigint and Double).
|
||||
// Note that instance is not Smi (checked above).
|
||||
if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
|
||||
if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
|
||||
GenerateNumberTypeCheck(
|
||||
kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
|
||||
return false;
|
||||
@@ -469,18 +473,18 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
FieldAddress(EDX, TypeArguments::type_at_offset(type_param.index())));
|
||||
// EDI: concrete type of type.
|
||||
// Check if type argument is dynamic.
|
||||
__ CompareObject(EDI, Type::ZoneHandle(Type::DynamicType()));
|
||||
__ CompareObject(EDI, Type::ZoneHandle(zone(), Type::DynamicType()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
__ CompareObject(EDI, Type::ZoneHandle(Type::ObjectType()));
|
||||
__ CompareObject(EDI, Type::ZoneHandle(zone(), Type::ObjectType()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
|
||||
// For Smi check quickly against int and num interfaces.
|
||||
Label not_smi;
|
||||
__ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi?
|
||||
__ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
|
||||
__ CompareObject(EDI, Type::ZoneHandle(Type::IntType()));
|
||||
__ CompareObject(EDI, Type::ZoneHandle(zone(), Type::IntType()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
__ CompareObject(EDI, Type::ZoneHandle(Type::Number()));
|
||||
__ CompareObject(EDI, Type::ZoneHandle(zone(), Type::Number()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
// Smi must be handled in runtime.
|
||||
Label fall_through;
|
||||
@@ -493,7 +497,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
const Register kTypeArgumentsReg = EDX;
|
||||
const Register kTempReg = EDI;
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(
|
||||
SubtypeTestCache::ZoneHandle(zone(),
|
||||
GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
|
||||
kInstanceReg,
|
||||
kTypeArgumentsReg,
|
||||
@@ -544,7 +548,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
|
||||
return SubtypeTestCache::null();
|
||||
}
|
||||
if (type.IsInstantiated()) {
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
// A class equality check is only applicable with a dst type of a
|
||||
// non-parameterized class, non-signature class, or with a raw dst type of
|
||||
// a parameterized class.
|
||||
@@ -615,7 +619,7 @@ void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline instanceof test.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, type,
|
||||
&is_instance, &is_not_instance);
|
||||
|
||||
@@ -716,7 +720,7 @@ void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline type check, linking to runtime call if not assignable.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, dst_type,
|
||||
&is_assignable, &runtime_call);
|
||||
|
||||
@@ -880,7 +884,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ jmp(&assign_optional_parameter, Assembler::kNearJump);
|
||||
__ Bind(&load_default_value);
|
||||
// Load EAX with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(
|
||||
param_pos - num_fixed_params));
|
||||
__ LoadObject(EAX, value);
|
||||
@@ -915,7 +919,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ cmpl(ECX, Immediate(param_pos));
|
||||
__ j(GREATER, &next_parameter, Assembler::kNearJump);
|
||||
// Load EAX with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(i));
|
||||
__ LoadObject(EAX, value);
|
||||
// Assign EAX to fp[kFirstLocalSlotFromFp - param_pos].
|
||||
@@ -1229,8 +1233,8 @@ void FlowGraphCompiler::EmitEdgeCounter() {
|
||||
// overflow; and though we do not reset the counters when we optimize or
|
||||
// deoptimize, there is a bound on the number of
|
||||
// optimization/deoptimization cycles we will attempt.
|
||||
const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(Smi::New(0)));
|
||||
const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
|
||||
__ Comment("Edge counter");
|
||||
__ LoadObject(EAX, counter);
|
||||
intptr_t increment_start = assembler_->CodeSize();
|
||||
@@ -1300,12 +1304,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ic_data.arguments_descriptor());
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
|
||||
table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = EDI;
|
||||
const Register cacheR = EBX;
|
||||
const Register targetR = EBX;
|
||||
@@ -1510,8 +1514,8 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
ASSERT(is_optimizing());
|
||||
__ Comment("EmitTestAndCall");
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
// Load receiver into EAX.
|
||||
__ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize));
|
||||
__ LoadObject(EDX, arguments_descriptor);
|
||||
@@ -1537,7 +1541,7 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
&StubCode::CallStaticFunctionLabel(),
|
||||
RawPcDescriptors::kOther,
|
||||
locs);
|
||||
const Function& function = Function::Handle(ic_data.GetTargetAt(0));
|
||||
const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
|
||||
AddStaticCallTarget(function);
|
||||
__ Drop(argument_count);
|
||||
if (kNumChecks > 1) {
|
||||
|
||||
@@ -94,15 +94,17 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// The real frame starts here.
|
||||
builder->MarkFrameStart();
|
||||
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
|
||||
// Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
|
||||
builder->AddPcMarker(Function::Handle(), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
|
||||
// Emit all values that are needed for materialization as a part of the
|
||||
// expression stack for the bottom-most frame. This guarantees that GC
|
||||
@@ -120,17 +122,19 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPp(
|
||||
Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
@@ -163,7 +167,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
|
||||
// For the outermost environment, set the incoming arguments.
|
||||
@@ -224,7 +228,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
|
||||
ASSERT(instance_reg == A0);
|
||||
ASSERT(temp_reg == kNoRegister); // Unused on MIPS.
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
|
||||
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
|
||||
__ LoadUniqueObject(A2, type_test_cache);
|
||||
if (test_kind == kTestTypeOneArg) {
|
||||
ASSERT(type_arguments_reg == kNoRegister);
|
||||
@@ -259,11 +263,11 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeWithArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
|
||||
const Register kInstanceReg = A0;
|
||||
Error& malformed_error = Error::Handle();
|
||||
const Type& int_type = Type::Handle(Type::IntType());
|
||||
Error& malformed_error = Error::Handle(zone());
|
||||
const Type& int_type = Type::Handle(zone(), Type::IntType());
|
||||
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
|
||||
// Malformed type should have been handled at graph construction time.
|
||||
ASSERT(smi_is_ok || malformed_error.IsNull());
|
||||
@@ -277,7 +281,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
const intptr_t num_type_params = type_class.NumTypeParameters();
|
||||
const intptr_t from_index = num_type_args - num_type_params;
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::ZoneHandle(type.arguments());
|
||||
TypeArguments::ZoneHandle(zone(), type.arguments());
|
||||
const bool is_raw_type = type_arguments.IsNull() ||
|
||||
type_arguments.IsRaw(from_index, num_type_params);
|
||||
// Signature class is an instantiated parameterized type.
|
||||
@@ -296,13 +300,13 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
}
|
||||
// If one type argument only, check if type argument is Object or dynamic.
|
||||
if (type_arguments.Length() == 1) {
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(zone(),
|
||||
type_arguments.TypeAt(0));
|
||||
ASSERT(!tp_argument.IsMalformed());
|
||||
if (tp_argument.IsType()) {
|
||||
ASSERT(tp_argument.HasResolvedTypeClass());
|
||||
// Check if type argument is dynamic or Object.
|
||||
const Type& object_type = Type::Handle(Type::ObjectType());
|
||||
const Type& object_type = Type::Handle(zone(), Type::ObjectType());
|
||||
if (object_type.IsSubtypeOf(tp_argument, NULL)) {
|
||||
// Instance class test only necessary.
|
||||
return GenerateSubtype1TestCacheLookup(
|
||||
@@ -348,16 +352,16 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeNoArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
const Class& type_class = Class::Handle(zone(), type.type_class());
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
|
||||
const Register kInstanceReg = A0;
|
||||
__ andi(T0, A0, Immediate(kSmiTagMask));
|
||||
// If instance is Smi, check directly.
|
||||
const Class& smi_class = Class::Handle(Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
|
||||
const Class& smi_class = Class::Handle(zone(), Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
|
||||
type_class,
|
||||
TypeArguments::Handle(),
|
||||
TypeArguments::Handle(zone()),
|
||||
NULL)) {
|
||||
__ beq(T0, ZR, is_instance_lbl);
|
||||
} else {
|
||||
@@ -384,7 +388,7 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
}
|
||||
// Custom checking for numbers (Smi, Mint, Bigint and Double).
|
||||
// Note that instance is not Smi (checked above).
|
||||
if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
|
||||
if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
|
||||
GenerateNumberTypeCheck(
|
||||
kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
|
||||
return false;
|
||||
@@ -452,15 +456,19 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
FieldAddress(A1, TypeArguments::type_at_offset(type_param.index())));
|
||||
// R2: concrete type of type.
|
||||
// Check if type argument is dynamic.
|
||||
__ BranchEqual(T2, Type::ZoneHandle(Type::DynamicType()), is_instance_lbl);
|
||||
__ BranchEqual(T2, Type::ZoneHandle(Type::ObjectType()), is_instance_lbl);
|
||||
__ BranchEqual(T2,
|
||||
Type::ZoneHandle(zone(), Type::DynamicType()), is_instance_lbl);
|
||||
__ BranchEqual(T2,
|
||||
Type::ZoneHandle(zone(), Type::ObjectType()), is_instance_lbl);
|
||||
|
||||
// For Smi check quickly against int and num interfaces.
|
||||
Label not_smi;
|
||||
__ andi(CMPRES1, A0, Immediate(kSmiTagMask));
|
||||
__ bne(CMPRES1, ZR, ¬_smi); // Value is Smi?
|
||||
__ BranchEqual(T2, Type::ZoneHandle(Type::IntType()), is_instance_lbl);
|
||||
__ BranchEqual(T2, Type::ZoneHandle(Type::Number()), is_instance_lbl);
|
||||
__ BranchEqual(T2,
|
||||
Type::ZoneHandle(zone(), Type::IntType()), is_instance_lbl);
|
||||
__ BranchEqual(T2,
|
||||
Type::ZoneHandle(zone(), Type::Number()), is_instance_lbl);
|
||||
// Smi must be handled in runtime.
|
||||
Label fall_through;
|
||||
__ b(&fall_through);
|
||||
@@ -472,7 +480,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
const Register kTypeArgumentsReg = A1;
|
||||
const Register kTempReg = kNoRegister;
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(
|
||||
SubtypeTestCache::ZoneHandle(zone(),
|
||||
GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
|
||||
kInstanceReg,
|
||||
kTypeArgumentsReg,
|
||||
@@ -523,7 +531,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
|
||||
return SubtypeTestCache::null();
|
||||
}
|
||||
if (type.IsInstantiated()) {
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
// A class equality check is only applicable with a dst type of a
|
||||
// non-parameterized class, non-signature class, or with a raw dst type of
|
||||
// a parameterized class.
|
||||
@@ -594,7 +602,7 @@ void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline instanceof test.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, type,
|
||||
&is_instance, &is_not_instance);
|
||||
|
||||
@@ -705,7 +713,7 @@ void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline type check, linking to runtime call if not assignable.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, dst_type,
|
||||
&is_assignable, &runtime_call);
|
||||
|
||||
@@ -872,7 +880,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
|
||||
__ Bind(&load_default_value);
|
||||
// Load T3 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(
|
||||
param_pos - num_fixed_params));
|
||||
__ LoadObject(T3, value);
|
||||
@@ -906,7 +914,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
const int param_pos = num_fixed_params + i;
|
||||
__ BranchSignedGreater(T2, Immediate(param_pos), &next_parameter);
|
||||
// Load T3 with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(i));
|
||||
__ LoadObject(T3, value);
|
||||
// Assign T3 to fp[kFirstLocalSlotFromFp - param_pos].
|
||||
@@ -1220,8 +1228,8 @@ void FlowGraphCompiler::EmitEdgeCounter() {
|
||||
// overflow; and though we do not reset the counters when we optimize or
|
||||
// deoptimize, there is a bound on the number of
|
||||
// optimization/deoptimization cycles we will attempt.
|
||||
const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(Smi::New(0)));
|
||||
const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
|
||||
__ Comment("Edge counter");
|
||||
__ LoadUniqueObject(T0, counter);
|
||||
__ lw(T1, FieldAddress(T0, Array::element_offset(0)));
|
||||
@@ -1237,7 +1245,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
// Each ICData propagated from unoptimized to optimized code contains the
|
||||
// function that corresponds to the Dart function of that IC call. Due
|
||||
// to inlining in optimized code, that function may not correspond to the
|
||||
@@ -1262,7 +1270,7 @@ void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
__ Comment("InstanceCall");
|
||||
__ LoadUniqueObject(S5, ic_data);
|
||||
GenerateDartCall(deopt_id,
|
||||
@@ -1282,12 +1290,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ic_data.arguments_descriptor());
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
__ Comment("MegamorphicInstanceCall");
|
||||
const Register receiverR = T0;
|
||||
const Register cacheR = T1;
|
||||
@@ -1541,8 +1549,8 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
ASSERT(is_optimizing());
|
||||
__ Comment("EmitTestAndCall");
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
|
||||
// Load receiver into T0.
|
||||
__ LoadFromOffset(T0, SP, (argument_count - 1) * kWordSize);
|
||||
@@ -1569,7 +1577,7 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
&StubCode::CallStaticFunctionLabel(),
|
||||
RawPcDescriptors::kOther,
|
||||
locs);
|
||||
const Function& function = Function::Handle(ic_data.GetTargetAt(0));
|
||||
const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
|
||||
AddStaticCallTarget(function);
|
||||
__ Drop(argument_count);
|
||||
if (kNumChecks > 1) {
|
||||
|
||||
@@ -98,11 +98,13 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// The real frame starts here.
|
||||
builder->MarkFrameStart();
|
||||
|
||||
Zone* zone = compiler->zone();
|
||||
|
||||
// Current PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(), slot_ix++);
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone), slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
|
||||
deopt_id(),
|
||||
slot_ix++);
|
||||
|
||||
@@ -122,16 +124,18 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
current = current->outer();
|
||||
while (current != NULL) {
|
||||
// PP, FP, and PC.
|
||||
builder->AddPp(Function::Handle(current->code().function()), slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPp(Function::Handle(zone, current->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
|
||||
// For any outer environment the deopt id is that of the call instruction
|
||||
// which is recorded in the outer environment.
|
||||
builder->AddReturnAddress(Function::Handle(current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
builder->AddReturnAddress(
|
||||
Function::Handle(zone, current->code().function()),
|
||||
Isolate::ToDeoptAfter(current->deopt_id()),
|
||||
slot_ix++);
|
||||
|
||||
// The values of outgoing arguments can be changed from the inlined call so
|
||||
// we must read them from the previous environment.
|
||||
@@ -160,7 +164,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
||||
// For the outermost environment, set caller PC, caller PP, and caller FP.
|
||||
builder->AddCallerPp(slot_ix++);
|
||||
// PC marker.
|
||||
builder->AddPcMarker(Function::Handle(previous->code().function()),
|
||||
builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
|
||||
slot_ix++);
|
||||
builder->AddCallerFp(slot_ix++);
|
||||
builder->AddCallerPc(slot_ix++);
|
||||
@@ -221,7 +225,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
|
||||
Label* is_instance_lbl,
|
||||
Label* is_not_instance_lbl) {
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
|
||||
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
|
||||
__ LoadUniqueObject(temp_reg, type_test_cache);
|
||||
__ pushq(temp_reg); // Subtype test cache.
|
||||
__ pushq(instance_reg); // Instance.
|
||||
@@ -263,11 +267,11 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeWithArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
|
||||
const Register kInstanceReg = RAX;
|
||||
Error& malformed_error = Error::Handle();
|
||||
const Type& int_type = Type::Handle(Type::IntType());
|
||||
Error& malformed_error = Error::Handle(zone());
|
||||
const Type& int_type = Type::Handle(zone(), Type::IntType());
|
||||
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
|
||||
// Malformed type should have been handled at graph construction time.
|
||||
ASSERT(smi_is_ok || malformed_error.IsNull());
|
||||
@@ -281,7 +285,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
const intptr_t num_type_params = type_class.NumTypeParameters();
|
||||
const intptr_t from_index = num_type_args - num_type_params;
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::ZoneHandle(type.arguments());
|
||||
TypeArguments::ZoneHandle(zone(), type.arguments());
|
||||
const bool is_raw_type = type_arguments.IsNull() ||
|
||||
type_arguments.IsRaw(from_index, num_type_params);
|
||||
// Signature class is an instantiated parameterized type.
|
||||
@@ -301,13 +305,13 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
|
||||
}
|
||||
// If one type argument only, check if type argument is Object or dynamic.
|
||||
if (type_arguments.Length() == 1) {
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(
|
||||
const AbstractType& tp_argument = AbstractType::ZoneHandle(zone(),
|
||||
type_arguments.TypeAt(0));
|
||||
ASSERT(!tp_argument.IsMalformed());
|
||||
if (tp_argument.IsType()) {
|
||||
ASSERT(tp_argument.HasResolvedTypeClass());
|
||||
// Check if type argument is dynamic or Object.
|
||||
const Type& object_type = Type::Handle(Type::ObjectType());
|
||||
const Type& object_type = Type::Handle(zone(), Type::ObjectType());
|
||||
if (object_type.IsSubtypeOf(tp_argument, NULL)) {
|
||||
// Instance class test only necessary.
|
||||
return GenerateSubtype1TestCacheLookup(
|
||||
@@ -352,16 +356,16 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
Label* is_not_instance_lbl) {
|
||||
__ Comment("InstantiatedTypeNoArgumentsTest");
|
||||
ASSERT(type.IsInstantiated());
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
const Class& type_class = Class::Handle(zone(), type.type_class());
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
|
||||
const Register kInstanceReg = RAX;
|
||||
__ testq(kInstanceReg, Immediate(kSmiTagMask));
|
||||
// If instance is Smi, check directly.
|
||||
const Class& smi_class = Class::Handle(Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
|
||||
const Class& smi_class = Class::Handle(zone(), Smi::Class());
|
||||
if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
|
||||
type_class,
|
||||
TypeArguments::Handle(),
|
||||
TypeArguments::Handle(zone()),
|
||||
NULL)) {
|
||||
__ j(ZERO, is_instance_lbl);
|
||||
} else {
|
||||
@@ -390,7 +394,7 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
|
||||
}
|
||||
// Custom checking for numbers (Smi, Mint, Bigint and Double).
|
||||
// Note that instance is not Smi (checked above).
|
||||
if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
|
||||
if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
|
||||
GenerateNumberTypeCheck(
|
||||
kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
|
||||
return false;
|
||||
@@ -460,9 +464,9 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
|
||||
// RDI: Concrete type of type.
|
||||
// Check if type argument is dynamic.
|
||||
__ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()));
|
||||
__ CompareObject(RDI, Type::ZoneHandle(zone(), Type::DynamicType()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
const Type& object_type = Type::ZoneHandle(Type::ObjectType());
|
||||
const Type& object_type = Type::ZoneHandle(zone(), Type::ObjectType());
|
||||
__ CompareObject(RDI, object_type);
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
|
||||
@@ -470,9 +474,9 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
Label not_smi;
|
||||
__ testq(RAX, Immediate(kSmiTagMask)); // Value is Smi?
|
||||
__ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
|
||||
__ CompareObject(RDI, Type::ZoneHandle(Type::IntType()));
|
||||
__ CompareObject(RDI, Type::ZoneHandle(zone(), Type::IntType()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
__ CompareObject(RDI, Type::ZoneHandle(Type::Number()));
|
||||
__ CompareObject(RDI, Type::ZoneHandle(zone(), Type::Number()));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
// Smi must be handled in runtime.
|
||||
Label fall_through;
|
||||
@@ -485,7 +489,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
|
||||
const Register kTypeArgumentsReg = RDX;
|
||||
const Register kTempReg = R10;
|
||||
const SubtypeTestCache& type_test_cache =
|
||||
SubtypeTestCache::ZoneHandle(
|
||||
SubtypeTestCache::ZoneHandle(zone(),
|
||||
GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
|
||||
kInstanceReg,
|
||||
kTypeArgumentsReg,
|
||||
@@ -536,7 +540,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
|
||||
return SubtypeTestCache::null();
|
||||
}
|
||||
if (type.IsInstantiated()) {
|
||||
const Class& type_class = Class::ZoneHandle(type.type_class());
|
||||
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
|
||||
// A class equality check is only applicable with a dst type of a
|
||||
// non-parameterized class, non-signature class, or with a raw dst type of
|
||||
// a parameterized class.
|
||||
@@ -605,7 +609,7 @@ void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline instanceof test.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, type,
|
||||
&is_instance, &is_not_instance);
|
||||
|
||||
@@ -704,7 +708,7 @@ void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
|
||||
}
|
||||
|
||||
// Generate inline type check, linking to runtime call if not assignable.
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
|
||||
SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
|
||||
test_cache = GenerateInlineInstanceof(token_pos, dst_type,
|
||||
&is_assignable, &runtime_call);
|
||||
|
||||
@@ -869,7 +873,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ jmp(&assign_optional_parameter, Assembler::kNearJump);
|
||||
__ Bind(&load_default_value);
|
||||
// Load RAX with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(
|
||||
param_pos - num_fixed_params));
|
||||
__ LoadObject(RAX, value);
|
||||
@@ -905,7 +909,7 @@ void FlowGraphCompiler::CopyParameters() {
|
||||
__ CompareImmediate(RCX, Immediate(param_pos));
|
||||
__ j(GREATER, &next_parameter, Assembler::kNearJump);
|
||||
// Load RAX with default argument.
|
||||
const Object& value = Object::ZoneHandle(
|
||||
const Object& value = Object::ZoneHandle(zone(),
|
||||
parsed_function().default_parameter_values().At(i));
|
||||
__ LoadObject(RAX, value);
|
||||
// Assign RAX to fp[kFirstLocalSlotFromFp - param_pos].
|
||||
@@ -1245,8 +1249,8 @@ void FlowGraphCompiler::EmitEdgeCounter() {
|
||||
// deoptimize, there is a bound on the number of
|
||||
// optimization/deoptimization cycles we will attempt.
|
||||
ASSERT(assembler_->constant_pool_allowed());
|
||||
const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(Smi::New(0)));
|
||||
const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
|
||||
counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
|
||||
__ Comment("Edge counter");
|
||||
__ LoadUniqueObject(RAX, counter);
|
||||
intptr_t increment_start = assembler_->CodeSize();
|
||||
@@ -1274,7 +1278,7 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
// Each ICData propagated from unoptimized to optimized code contains the
|
||||
// function that corresponds to the Dart function of that IC call. Due
|
||||
// to inlining in optimized code, that function may not correspond to the
|
||||
@@ -1298,7 +1302,7 @@ void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
|
||||
intptr_t deopt_id,
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
|
||||
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
|
||||
__ LoadUniqueObject(RBX, ic_data);
|
||||
GenerateDartCall(deopt_id,
|
||||
token_pos,
|
||||
@@ -1316,12 +1320,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
intptr_t token_pos,
|
||||
LocationSummary* locs) {
|
||||
MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
|
||||
const String& name = String::Handle(ic_data.target_name());
|
||||
const String& name = String::Handle(zone(), ic_data.target_name());
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ic_data.arguments_descriptor());
|
||||
Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
|
||||
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
|
||||
const MegamorphicCache& cache =
|
||||
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
|
||||
const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
|
||||
zone(), table->Lookup(name, arguments_descriptor));
|
||||
const Register receiverR = RDI;
|
||||
const Register cacheR = RBX;
|
||||
const Register targetR = RCX;
|
||||
@@ -1482,8 +1486,8 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
|
||||
__ Comment("EmitTestAndCall");
|
||||
const Array& arguments_descriptor =
|
||||
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
|
||||
argument_names));
|
||||
// Load receiver into RAX.
|
||||
__ movq(RAX,
|
||||
Address(RSP, (argument_count - 1) * kWordSize));
|
||||
@@ -1510,7 +1514,7 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
||||
&StubCode::CallStaticFunctionLabel(),
|
||||
RawPcDescriptors::kOther,
|
||||
locs);
|
||||
const Function& function = Function::Handle(ic_data.GetTargetAt(0));
|
||||
const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
|
||||
AddStaticCallTarget(function);
|
||||
__ Drop(argument_count, RCX);
|
||||
if (kNumChecks > 1) {
|
||||
|
||||
@@ -49,7 +49,19 @@ Definition::Definition(intptr_t deopt_id)
|
||||
ssa_temp_index_(-1),
|
||||
input_use_list_(NULL),
|
||||
env_use_list_(NULL),
|
||||
constant_value_(Object::ZoneHandle(ConstantPropagator::Unknown())) {
|
||||
constant_value_(NULL) {
|
||||
}
|
||||
|
||||
|
||||
// A value in the constant propagation lattice.
|
||||
// - non-constant sentinel
|
||||
// - a constant (any non-sentinel value)
|
||||
// - unknown sentinel
|
||||
Object& Definition::constant_value() {
|
||||
if (constant_value_ == NULL) {
|
||||
constant_value_ = &Object::ZoneHandle(ConstantPropagator::Unknown());
|
||||
}
|
||||
return *constant_value_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1748,7 +1748,7 @@ class Definition : public Instruction {
|
||||
// - non-constant sentinel
|
||||
// - a constant (any non-sentinel value)
|
||||
// - unknown sentinel
|
||||
Object& constant_value() const { return constant_value_; }
|
||||
Object& constant_value();
|
||||
|
||||
virtual void InferRange(RangeAnalysis* analysis, Range* range);
|
||||
|
||||
@@ -1801,7 +1801,7 @@ class Definition : public Instruction {
|
||||
Value* input_use_list_;
|
||||
Value* env_use_list_;
|
||||
|
||||
Object& constant_value_;
|
||||
Object* constant_value_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Definition);
|
||||
};
|
||||
|
||||
@@ -48,6 +48,7 @@ DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
|
||||
|
||||
DECLARE_FLAG(bool, lazy_dispatchers);
|
||||
DECLARE_FLAG(bool, load_deferred_eagerly);
|
||||
DECLARE_FLAG(bool, profile_vm);
|
||||
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
|
||||
DECLARE_FLAG(bool, warn_on_javascript_compatibility);
|
||||
|
||||
@@ -836,6 +837,9 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
|
||||
Zone* zone = parsed_function->zone();
|
||||
CSTAT_TIMER_SCOPE(isolate, parser_timer);
|
||||
INC_STAT(isolate, num_functions_compiled, 1);
|
||||
VMTagScope tagScope(isolate, VMTag::kCompileParseFunctionTagId,
|
||||
FLAG_profile_vm);
|
||||
|
||||
ASSERT(isolate->long_jump_base()->IsSafeToJump());
|
||||
ASSERT(parsed_function != NULL);
|
||||
const Function& func = parsed_function->function();
|
||||
|
||||
@@ -217,6 +217,8 @@ RegExpParser::RegExpParser(const String& in,
|
||||
|
||||
|
||||
bool RegExpParser::ParseFunction(ParsedFunction *parsed_function) {
|
||||
VMTagScope tagScope(Thread::Current()->isolate(),
|
||||
VMTag::kCompileParseRegExpTagId);
|
||||
Zone* zone = parsed_function->zone();
|
||||
JSRegExp& regexp = JSRegExp::Handle(parsed_function->function().regexp());
|
||||
|
||||
|
||||
+4
-2
@@ -81,11 +81,13 @@ VMTag::TagEntry VMTag::entries_[] = {
|
||||
};
|
||||
|
||||
|
||||
VMTagScope::VMTagScope(Isolate* base_isolate, uword tag)
|
||||
VMTagScope::VMTagScope(Isolate* base_isolate, uword tag, bool conditional_set)
|
||||
: StackResource(base_isolate) {
|
||||
ASSERT(isolate() != NULL);
|
||||
previous_tag_ = isolate()->vm_tag();
|
||||
isolate()->set_vm_tag(tag);
|
||||
if (conditional_set) {
|
||||
isolate()->set_vm_tag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-1
@@ -22,6 +22,9 @@ class RuntimeEntry;
|
||||
V(CompileClass) \
|
||||
V(CompileTopLevel) \
|
||||
V(CompileScanner) \
|
||||
V(CompileParseFunction) \
|
||||
V(CompileParseRegExp) \
|
||||
V(CompileFlowGraphBuilder) \
|
||||
V(Dart) \
|
||||
V(GCNewSpace) \
|
||||
V(GCOldSpace) \
|
||||
@@ -65,7 +68,7 @@ class VMTag : public AllStatic {
|
||||
|
||||
class VMTagScope : StackResource {
|
||||
public:
|
||||
VMTagScope(Isolate* isolate, uword tag);
|
||||
VMTagScope(Isolate* isolate, uword tag, bool conditional_set = true);
|
||||
~VMTagScope();
|
||||
private:
|
||||
uword previous_tag_;
|
||||
|
||||
Reference in New Issue
Block a user