From 1a1ff00a29f7befdb9065cf2a9504c0c172b1cc6 Mon Sep 17 00:00:00 2001 From: Srdjan Mitrovic Date: Mon, 3 Aug 2015 10:10:24 -0700 Subject: [PATCH] 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 . --- runtime/vm/constant_propagator.cc | 2 +- runtime/vm/flow_graph_builder.cc | 4 ++ runtime/vm/flow_graph_compiler_arm.cc | 88 ++++++++++++----------- runtime/vm/flow_graph_compiler_arm64.cc | 88 ++++++++++++----------- runtime/vm/flow_graph_compiler_ia32.cc | 80 +++++++++++---------- runtime/vm/flow_graph_compiler_mips.cc | 92 ++++++++++++++----------- runtime/vm/flow_graph_compiler_x64.cc | 88 ++++++++++++----------- runtime/vm/intermediate_language.cc | 14 +++- runtime/vm/intermediate_language.h | 4 +- runtime/vm/parser.cc | 4 ++ runtime/vm/regexp_parser.cc | 2 + runtime/vm/tags.cc | 6 +- runtime/vm/tags.h | 5 +- 13 files changed, 264 insertions(+), 213 deletions(-) diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc index 35bab84f004..29818e18b84 100644 --- a/runtime/vm/constant_propagator.cc +++ b/runtime/vm/constant_propagator.cc @@ -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(); diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc index 8a66665bd16..ce0fb5a5dc3 100644 --- a/runtime/vm/flow_graph_builder.cc +++ b/runtime/vm/flow_graph_builder.cc @@ -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()); diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc index df9d3cc8603..89e55443976 100644 --- a/runtime/vm/flow_graph_compiler_arm.cc +++ b/runtime/vm/flow_graph_compiler_arm.cc @@ -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) { diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc index 85e52de2c7d..39c1206b421 100644 --- a/runtime/vm/flow_graph_compiler_arm64.cc +++ b/runtime/vm/flow_graph_compiler_arm64.cc @@ -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) { diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc index e7202f2f956..0bcc4f2e32b 100644 --- a/runtime/vm/flow_graph_compiler_ia32.cc +++ b/runtime/vm/flow_graph_compiler_ia32.cc @@ -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(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) { diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc index 06e2c5bcc83..8dd9ab1af09 100644 --- a/runtime/vm/flow_graph_compiler_mips.cc +++ b/runtime/vm/flow_graph_compiler_mips.cc @@ -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) { diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc index b8b89d7d17e..a206f52210d 100644 --- a/runtime/vm/flow_graph_compiler_x64.cc +++ b/runtime/vm/flow_graph_compiler_x64.cc @@ -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) { diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc index 1ba2c3f1992..d05c601b87d 100644 --- a/runtime/vm/intermediate_language.cc +++ b/runtime/vm/intermediate_language.cc @@ -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_; } diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h index c9436800f88..44919ffa945 100644 --- a/runtime/vm/intermediate_language.h +++ b/runtime/vm/intermediate_language.h @@ -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); }; diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 00acf39c96d..0a15dfd6d64 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -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(); diff --git a/runtime/vm/regexp_parser.cc b/runtime/vm/regexp_parser.cc index 03abf5a5a57..716afa46427 100644 --- a/runtime/vm/regexp_parser.cc +++ b/runtime/vm/regexp_parser.cc @@ -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()); diff --git a/runtime/vm/tags.cc b/runtime/vm/tags.cc index 50e5e237d34..ffd224f7aa4 100644 --- a/runtime/vm/tags.cc +++ b/runtime/vm/tags.cc @@ -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); + } } diff --git a/runtime/vm/tags.h b/runtime/vm/tags.h index e0077cbe025..b293663842c 100644 --- a/runtime/vm/tags.h +++ b/runtime/vm/tags.h @@ -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_;