OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/constant_propagator.h" | 8 #include "vm/constant_propagator.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 it.CurrentValue()->RemoveFromUseList(); | 762 it.CurrentValue()->RemoveFromUseList(); |
763 } | 763 } |
764 } | 764 } |
765 | 765 |
766 | 766 |
767 void Instruction::InheritDeoptTargetAfter(FlowGraph* flow_graph, | 767 void Instruction::InheritDeoptTargetAfter(FlowGraph* flow_graph, |
768 Definition* call, | 768 Definition* call, |
769 Definition* result) { | 769 Definition* result) { |
770 ASSERT(call->env() != NULL); | 770 ASSERT(call->env() != NULL); |
771 deopt_id_ = Isolate::ToDeoptAfter(call->deopt_id_); | 771 deopt_id_ = Isolate::ToDeoptAfter(call->deopt_id_); |
772 call->env()->DeepCopyAfterTo(flow_graph->isolate(), | 772 call->env()->DeepCopyAfterTo(flow_graph->zone(), |
773 this, | 773 this, |
774 call->ArgumentCount(), | 774 call->ArgumentCount(), |
775 flow_graph->constant_dead(), | 775 flow_graph->constant_dead(), |
776 result != NULL ? result | 776 result != NULL ? result |
777 : flow_graph->constant_dead()); | 777 : flow_graph->constant_dead()); |
778 env()->set_deopt_id(deopt_id_); | 778 env()->set_deopt_id(deopt_id_); |
779 } | 779 } |
780 | 780 |
781 | 781 |
782 void Instruction::InheritDeoptTarget(Isolate* isolate, Instruction* other) { | 782 void Instruction::InheritDeoptTarget(Zone* zone, Instruction* other) { |
783 ASSERT(other->env() != NULL); | 783 ASSERT(other->env() != NULL); |
784 CopyDeoptIdFrom(*other); | 784 CopyDeoptIdFrom(*other); |
785 other->env()->DeepCopyTo(isolate, this); | 785 other->env()->DeepCopyTo(zone, this); |
786 env()->set_deopt_id(deopt_id_); | 786 env()->set_deopt_id(deopt_id_); |
787 } | 787 } |
788 | 788 |
789 | 789 |
790 void BranchInstr::InheritDeoptTarget(Isolate* isolate, Instruction* other) { | 790 void BranchInstr::InheritDeoptTarget(Zone* zone, Instruction* other) { |
791 ASSERT(env() == NULL); | 791 ASSERT(env() == NULL); |
792 Instruction::InheritDeoptTarget(isolate, other); | 792 Instruction::InheritDeoptTarget(zone, other); |
793 comparison()->SetDeoptId(*this); | 793 comparison()->SetDeoptId(*this); |
794 } | 794 } |
795 | 795 |
796 | 796 |
797 bool Instruction::IsDominatedBy(Instruction* dom) { | 797 bool Instruction::IsDominatedBy(Instruction* dom) { |
798 BlockEntryInstr* block = GetBlock(); | 798 BlockEntryInstr* block = GetBlock(); |
799 BlockEntryInstr* dom_block = dom->GetBlock(); | 799 BlockEntryInstr* dom_block = dom->GetBlock(); |
800 | 800 |
801 if (dom->IsPhi()) { | 801 if (dom->IsPhi()) { |
802 dom = dom_block; | 802 dom = dom_block; |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2116 if ((box_defn != NULL) && | 2116 if ((box_defn != NULL) && |
2117 (box_defn->from_representation() == representation())) { | 2117 (box_defn->from_representation() == representation())) { |
2118 return box_defn->value()->definition(); | 2118 return box_defn->value()->definition(); |
2119 } | 2119 } |
2120 | 2120 |
2121 if ((representation() == kUnboxedDouble) && value()->BindsToConstant()) { | 2121 if ((representation() == kUnboxedDouble) && value()->BindsToConstant()) { |
2122 UnboxedConstantInstr* uc = NULL; | 2122 UnboxedConstantInstr* uc = NULL; |
2123 | 2123 |
2124 const Object& val = value()->BoundConstant(); | 2124 const Object& val = value()->BoundConstant(); |
2125 if (val.IsSmi()) { | 2125 if (val.IsSmi()) { |
2126 const Double& double_val = Double::ZoneHandle(flow_graph->isolate(), | 2126 const Double& double_val = Double::ZoneHandle(flow_graph->zone(), |
2127 Double::NewCanonical(Smi::Cast(val).AsDoubleValue())); | 2127 Double::NewCanonical(Smi::Cast(val).AsDoubleValue())); |
2128 uc = new UnboxedConstantInstr(double_val, kUnboxedDouble); | 2128 uc = new UnboxedConstantInstr(double_val, kUnboxedDouble); |
2129 } else if (val.IsDouble()) { | 2129 } else if (val.IsDouble()) { |
2130 uc = new UnboxedConstantInstr(val, kUnboxedDouble); | 2130 uc = new UnboxedConstantInstr(val, kUnboxedDouble); |
2131 } | 2131 } |
2132 | 2132 |
2133 if (uc != NULL) { | 2133 if (uc != NULL) { |
2134 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); | 2134 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); |
2135 return uc; | 2135 return uc; |
2136 } | 2136 } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 // so we need to negate original comparison. | 2384 // so we need to negate original comparison. |
2385 *negate = true; | 2385 *negate = true; |
2386 return true; | 2386 return true; |
2387 } | 2387 } |
2388 | 2388 |
2389 return false; | 2389 return false; |
2390 } | 2390 } |
2391 | 2391 |
2392 | 2392 |
2393 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) { | 2393 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) { |
2394 Isolate* isolate = flow_graph->isolate(); | 2394 Zone* zone = flow_graph->zone(); |
2395 // Only handle strict-compares. | 2395 // Only handle strict-compares. |
2396 if (comparison()->IsStrictCompare()) { | 2396 if (comparison()->IsStrictCompare()) { |
2397 bool negated = false; | 2397 bool negated = false; |
2398 Definition* replacement = | 2398 Definition* replacement = |
2399 CanonicalizeStrictCompare(comparison()->AsStrictCompare(), &negated); | 2399 CanonicalizeStrictCompare(comparison()->AsStrictCompare(), &negated); |
2400 if (replacement == comparison()) { | 2400 if (replacement == comparison()) { |
2401 return this; | 2401 return this; |
2402 } | 2402 } |
2403 ComparisonInstr* comp = replacement->AsComparison(); | 2403 ComparisonInstr* comp = replacement->AsComparison(); |
2404 if ((comp == NULL) || | 2404 if ((comp == NULL) || |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2445 bit_and = comparison()->right()->definition()->AsBinarySmiOp(); | 2445 bit_and = comparison()->right()->definition()->AsBinarySmiOp(); |
2446 } | 2446 } |
2447 if (bit_and != NULL) { | 2447 if (bit_and != NULL) { |
2448 if (FLAG_trace_optimization) { | 2448 if (FLAG_trace_optimization) { |
2449 OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index()); | 2449 OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index()); |
2450 } | 2450 } |
2451 TestSmiInstr* test = new TestSmiInstr( | 2451 TestSmiInstr* test = new TestSmiInstr( |
2452 comparison()->token_pos(), | 2452 comparison()->token_pos(), |
2453 negate ? Token::NegateComparison(comparison()->kind()) | 2453 negate ? Token::NegateComparison(comparison()->kind()) |
2454 : comparison()->kind(), | 2454 : comparison()->kind(), |
2455 bit_and->left()->Copy(isolate), | 2455 bit_and->left()->Copy(zone), |
2456 bit_and->right()->Copy(isolate)); | 2456 bit_and->right()->Copy(zone)); |
2457 ASSERT(!CanDeoptimize()); | 2457 ASSERT(!CanDeoptimize()); |
2458 RemoveEnvironment(); | 2458 RemoveEnvironment(); |
2459 flow_graph->CopyDeoptTarget(this, bit_and); | 2459 flow_graph->CopyDeoptTarget(this, bit_and); |
2460 SetComparison(test); | 2460 SetComparison(test); |
2461 bit_and->RemoveFromGraph(); | 2461 bit_and->RemoveFromGraph(); |
2462 } | 2462 } |
2463 } | 2463 } |
2464 return this; | 2464 return this; |
2465 } | 2465 } |
2466 | 2466 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | 2687 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
2688 GetDeoptId(), | 2688 GetDeoptId(), |
2689 Scanner::kNoSourcePos); | 2689 Scanner::kNoSourcePos); |
2690 } | 2690 } |
2691 if (HasParallelMove()) { | 2691 if (HasParallelMove()) { |
2692 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 2692 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
2693 } | 2693 } |
2694 } | 2694 } |
2695 | 2695 |
2696 | 2696 |
2697 void IndirectGotoInstr::ComputeOffsetTable(Isolate* isolate) { | 2697 void IndirectGotoInstr::ComputeOffsetTable() { |
2698 if (GetBlock()->offset() < 0) { | 2698 if (GetBlock()->offset() < 0) { |
2699 // Don't generate a table when contained in an unreachable block. | 2699 // Don't generate a table when contained in an unreachable block. |
2700 return; | 2700 return; |
2701 } | 2701 } |
2702 ASSERT(SuccessorCount() == offsets_.Length()); | 2702 ASSERT(SuccessorCount() == offsets_.Length()); |
2703 intptr_t element_size = offsets_.ElementSizeInBytes(); | 2703 intptr_t element_size = offsets_.ElementSizeInBytes(); |
2704 for (intptr_t i = 0; i < SuccessorCount(); i++) { | 2704 for (intptr_t i = 0; i < SuccessorCount(); i++) { |
2705 TargetEntryInstr* target = SuccessorAt(i); | 2705 TargetEntryInstr* target = SuccessorAt(i); |
2706 intptr_t offset = target->offset(); | 2706 intptr_t offset = target->offset(); |
2707 | 2707 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2917 switch (kind) { | 2917 switch (kind) { |
2918 case Token::kADD: return stub_code->SmiAddInlineCacheEntryPoint(); | 2918 case Token::kADD: return stub_code->SmiAddInlineCacheEntryPoint(); |
2919 case Token::kSUB: return stub_code->SmiSubInlineCacheEntryPoint(); | 2919 case Token::kSUB: return stub_code->SmiSubInlineCacheEntryPoint(); |
2920 case Token::kEQ: return stub_code->SmiEqualInlineCacheEntryPoint(); | 2920 case Token::kEQ: return stub_code->SmiEqualInlineCacheEntryPoint(); |
2921 default: return 0; | 2921 default: return 0; |
2922 } | 2922 } |
2923 } | 2923 } |
2924 | 2924 |
2925 | 2925 |
2926 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2926 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2927 Isolate* isolate = compiler->isolate(); | 2927 Zone* zone = compiler->zone(); |
2928 const ICData* call_ic_data = NULL; | 2928 const ICData* call_ic_data = NULL; |
2929 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { | 2929 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { |
2930 const Array& arguments_descriptor = | 2930 const Array& arguments_descriptor = |
2931 Array::Handle(isolate, ArgumentsDescriptor::New(ArgumentCount(), | 2931 Array::Handle(zone, ArgumentsDescriptor::New(ArgumentCount(), |
2932 argument_names())); | 2932 argument_names())); |
2933 call_ic_data = compiler->GetOrAddInstanceCallICData( | 2933 call_ic_data = compiler->GetOrAddInstanceCallICData( |
2934 deopt_id(), function_name(), arguments_descriptor, | 2934 deopt_id(), function_name(), arguments_descriptor, |
2935 checked_argument_count()); | 2935 checked_argument_count()); |
2936 } else { | 2936 } else { |
2937 call_ic_data = &ICData::ZoneHandle(isolate, ic_data()->raw()); | 2937 call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); |
2938 } | 2938 } |
2939 if (compiler->is_optimizing()) { | 2939 if (compiler->is_optimizing()) { |
2940 ASSERT(HasICData()); | 2940 ASSERT(HasICData()); |
2941 if (ic_data()->NumberOfUsedChecks() > 0) { | 2941 if (ic_data()->NumberOfUsedChecks() > 0) { |
2942 const ICData& unary_ic_data = | 2942 const ICData& unary_ic_data = |
2943 ICData::ZoneHandle(isolate, ic_data()->AsUnaryClassChecks()); | 2943 ICData::ZoneHandle(zone, ic_data()->AsUnaryClassChecks()); |
2944 compiler->GenerateInstanceCall(deopt_id(), | 2944 compiler->GenerateInstanceCall(deopt_id(), |
2945 token_pos(), | 2945 token_pos(), |
2946 ArgumentCount(), | 2946 ArgumentCount(), |
2947 locs(), | 2947 locs(), |
2948 unary_ic_data); | 2948 unary_ic_data); |
2949 } else { | 2949 } else { |
2950 // Call was not visited yet, use original ICData in order to populate it. | 2950 // Call was not visited yet, use original ICData in order to populate it. |
2951 compiler->GenerateInstanceCall(deopt_id(), | 2951 compiler->GenerateInstanceCall(deopt_id(), |
2952 token_pos(), | 2952 token_pos(), |
2953 ArgumentCount(), | 2953 ArgumentCount(), |
2954 locs(), | 2954 locs(), |
2955 *call_ic_data); | 2955 *call_ic_data); |
2956 } | 2956 } |
2957 } else { | 2957 } else { |
2958 // Unoptimized code. | 2958 // Unoptimized code. |
2959 ASSERT(!HasICData()); | 2959 ASSERT(!HasICData()); |
2960 bool is_smi_two_args_op = false; | 2960 bool is_smi_two_args_op = false; |
2961 const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind()); | 2961 const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind()); |
2962 if (label_address != 0) { | 2962 if (label_address != 0) { |
2963 // We have a dedicated inline cache stub for this operation, add an | 2963 // We have a dedicated inline cache stub for this operation, add an |
2964 // an initial Smi/Smi check with count 0. | 2964 // an initial Smi/Smi check with count 0. |
2965 ASSERT(call_ic_data->NumArgsTested() == 2); | 2965 ASSERT(call_ic_data->NumArgsTested() == 2); |
2966 const String& name = String::Handle(isolate, call_ic_data->target_name()); | 2966 const String& name = String::Handle(zone, call_ic_data->target_name()); |
2967 const Class& smi_class = Class::Handle(isolate, Smi::Class()); | 2967 const Class& smi_class = Class::Handle(zone, Smi::Class()); |
2968 const Function& smi_op_target = | 2968 const Function& smi_op_target = |
2969 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); | 2969 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); |
2970 if (call_ic_data->NumberOfChecks() == 0) { | 2970 if (call_ic_data->NumberOfChecks() == 0) { |
2971 GrowableArray<intptr_t> class_ids(2); | 2971 GrowableArray<intptr_t> class_ids(2); |
2972 class_ids.Add(kSmiCid); | 2972 class_ids.Add(kSmiCid); |
2973 class_ids.Add(kSmiCid); | 2973 class_ids.Add(kSmiCid); |
2974 call_ic_data->AddCheck(class_ids, smi_op_target); | 2974 call_ic_data->AddCheck(class_ids, smi_op_target); |
2975 // 'AddCheck' sets the initial count to 1. | 2975 // 'AddCheck' sets the initial count to 1. |
2976 call_ic_data->SetCountAt(0, 0); | 2976 call_ic_data->SetCountAt(0, 0); |
2977 is_smi_two_args_op = true; | 2977 is_smi_two_args_op = true; |
2978 } else if (call_ic_data->NumberOfChecks() == 1) { | 2978 } else if (call_ic_data->NumberOfChecks() == 1) { |
2979 GrowableArray<intptr_t> class_ids(2); | 2979 GrowableArray<intptr_t> class_ids(2); |
2980 Function& target = Function::Handle(isolate); | 2980 Function& target = Function::Handle(zone); |
2981 call_ic_data->GetCheckAt(0, &class_ids, &target); | 2981 call_ic_data->GetCheckAt(0, &class_ids, &target); |
2982 if ((target.raw() == smi_op_target.raw()) && | 2982 if ((target.raw() == smi_op_target.raw()) && |
2983 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { | 2983 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { |
2984 is_smi_two_args_op = true; | 2984 is_smi_two_args_op = true; |
2985 } | 2985 } |
2986 } | 2986 } |
2987 } | 2987 } |
2988 if (is_smi_two_args_op) { | 2988 if (is_smi_two_args_op) { |
2989 ASSERT(ArgumentCount() == 2); | 2989 ASSERT(ArgumentCount() == 2); |
2990 ExternalLabel target_label(label_address); | 2990 ExternalLabel target_label(label_address); |
2991 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | 2991 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), |
2992 deopt_id(), token_pos(), locs()); | 2992 deopt_id(), token_pos(), locs()); |
2993 } else if (FLAG_ic_range_profiling && | 2993 } else if (FLAG_ic_range_profiling && |
2994 (Token::IsBinaryArithmeticOperator(token_kind()) || | 2994 (Token::IsBinaryArithmeticOperator(token_kind()) || |
2995 Token::IsUnaryArithmeticOperator(token_kind()))) { | 2995 Token::IsUnaryArithmeticOperator(token_kind()))) { |
2996 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == | 2996 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == |
2997 (ArgumentCount() == 1)); | 2997 (ArgumentCount() == 1)); |
2998 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == | 2998 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == |
2999 (ArgumentCount() == 2)); | 2999 (ArgumentCount() == 2)); |
3000 StubCode* stub_code = isolate->stub_code(); | 3000 StubCode* stub_code = compiler->isolate()->stub_code(); |
3001 ExternalLabel target_label((ArgumentCount() == 1) ? | 3001 ExternalLabel target_label((ArgumentCount() == 1) ? |
3002 stub_code->UnaryRangeCollectingInlineCacheEntryPoint() : | 3002 stub_code->UnaryRangeCollectingInlineCacheEntryPoint() : |
3003 stub_code->BinaryRangeCollectingInlineCacheEntryPoint()); | 3003 stub_code->BinaryRangeCollectingInlineCacheEntryPoint()); |
3004 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | 3004 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), |
3005 deopt_id(), token_pos(), locs()); | 3005 deopt_id(), token_pos(), locs()); |
3006 } else { | 3006 } else { |
3007 compiler->GenerateInstanceCall(deopt_id(), | 3007 compiler->GenerateInstanceCall(deopt_id(), |
3008 token_pos(), | 3008 token_pos(), |
3009 ArgumentCount(), | 3009 ArgumentCount(), |
3010 locs(), | 3010 locs(), |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3089 bool opt) const { | 3089 bool opt) const { |
3090 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall); | 3090 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall); |
3091 } | 3091 } |
3092 | 3092 |
3093 | 3093 |
3094 void DeoptimizeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3094 void DeoptimizeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3095 __ Jump(compiler->AddDeoptStub(deopt_id(), deopt_reason_)); | 3095 __ Jump(compiler->AddDeoptStub(deopt_id(), deopt_reason_)); |
3096 } | 3096 } |
3097 | 3097 |
3098 | 3098 |
3099 Environment* Environment::From(Isolate* isolate, | 3099 Environment* Environment::From(Zone* zone, |
3100 const GrowableArray<Definition*>& definitions, | 3100 const GrowableArray<Definition*>& definitions, |
3101 intptr_t fixed_parameter_count, | 3101 intptr_t fixed_parameter_count, |
3102 const ParsedFunction& parsed_function) { | 3102 const ParsedFunction& parsed_function) { |
3103 Environment* env = | 3103 Environment* env = |
3104 new(isolate) Environment(definitions.length(), | 3104 new(zone) Environment(definitions.length(), |
3105 fixed_parameter_count, | 3105 fixed_parameter_count, |
3106 Isolate::kNoDeoptId, | 3106 Isolate::kNoDeoptId, |
3107 parsed_function, | 3107 parsed_function, |
3108 NULL); | 3108 NULL); |
3109 for (intptr_t i = 0; i < definitions.length(); ++i) { | 3109 for (intptr_t i = 0; i < definitions.length(); ++i) { |
3110 env->values_.Add(new(isolate) Value(definitions[i])); | 3110 env->values_.Add(new(zone) Value(definitions[i])); |
3111 } | 3111 } |
3112 return env; | 3112 return env; |
3113 } | 3113 } |
3114 | 3114 |
3115 | 3115 |
3116 Environment* Environment::DeepCopy(Isolate* isolate, intptr_t length) const { | 3116 Environment* Environment::DeepCopy(Zone* zone, intptr_t length) const { |
3117 ASSERT(length <= values_.length()); | 3117 ASSERT(length <= values_.length()); |
3118 Environment* copy = new(isolate) Environment( | 3118 Environment* copy = new(zone) Environment( |
3119 length, | 3119 length, |
3120 fixed_parameter_count_, | 3120 fixed_parameter_count_, |
3121 deopt_id_, | 3121 deopt_id_, |
3122 parsed_function_, | 3122 parsed_function_, |
3123 (outer_ == NULL) ? NULL : outer_->DeepCopy(isolate)); | 3123 (outer_ == NULL) ? NULL : outer_->DeepCopy(zone)); |
3124 if (locations_ != NULL) { | 3124 if (locations_ != NULL) { |
3125 Location* new_locations = isolate->current_zone()->Alloc<Location>(length); | 3125 Location* new_locations = zone->Alloc<Location>(length); |
3126 copy->set_locations(new_locations); | 3126 copy->set_locations(new_locations); |
3127 } | 3127 } |
3128 for (intptr_t i = 0; i < length; ++i) { | 3128 for (intptr_t i = 0; i < length; ++i) { |
3129 copy->values_.Add(values_[i]->Copy(isolate)); | 3129 copy->values_.Add(values_[i]->Copy(zone)); |
3130 if (locations_ != NULL) { | 3130 if (locations_ != NULL) { |
3131 copy->locations_[i] = locations_[i].Copy(); | 3131 copy->locations_[i] = locations_[i].Copy(); |
3132 } | 3132 } |
3133 } | 3133 } |
3134 return copy; | 3134 return copy; |
3135 } | 3135 } |
3136 | 3136 |
3137 | 3137 |
3138 // Copies the environment and updates the environment use lists. | 3138 // Copies the environment and updates the environment use lists. |
3139 void Environment::DeepCopyTo(Isolate* isolate, Instruction* instr) const { | 3139 void Environment::DeepCopyTo(Zone* zone, Instruction* instr) const { |
3140 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { | 3140 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { |
3141 it.CurrentValue()->RemoveFromUseList(); | 3141 it.CurrentValue()->RemoveFromUseList(); |
3142 } | 3142 } |
3143 | 3143 |
3144 Environment* copy = DeepCopy(isolate); | 3144 Environment* copy = DeepCopy(zone); |
3145 instr->SetEnvironment(copy); | 3145 instr->SetEnvironment(copy); |
3146 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 3146 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
3147 Value* value = it.CurrentValue(); | 3147 Value* value = it.CurrentValue(); |
3148 value->definition()->AddEnvUse(value); | 3148 value->definition()->AddEnvUse(value); |
3149 } | 3149 } |
3150 } | 3150 } |
3151 | 3151 |
3152 | 3152 |
3153 void Environment::DeepCopyAfterTo(Isolate* isolate, | 3153 void Environment::DeepCopyAfterTo(Zone* zone, |
3154 Instruction* instr, | 3154 Instruction* instr, |
3155 intptr_t argc, | 3155 intptr_t argc, |
3156 Definition* dead, | 3156 Definition* dead, |
3157 Definition* result) const { | 3157 Definition* result) const { |
3158 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { | 3158 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { |
3159 it.CurrentValue()->RemoveFromUseList(); | 3159 it.CurrentValue()->RemoveFromUseList(); |
3160 } | 3160 } |
3161 | 3161 |
3162 Environment* copy = DeepCopy(isolate, values_.length() - argc); | 3162 Environment* copy = DeepCopy(zone, values_.length() - argc); |
3163 for (intptr_t i = 0; i < argc; i++) { | 3163 for (intptr_t i = 0; i < argc; i++) { |
3164 copy->values_.Add(new(isolate) Value(dead)); | 3164 copy->values_.Add(new(zone) Value(dead)); |
3165 } | 3165 } |
3166 copy->values_.Add(new(isolate) Value(result)); | 3166 copy->values_.Add(new(zone) Value(result)); |
3167 | 3167 |
3168 instr->SetEnvironment(copy); | 3168 instr->SetEnvironment(copy); |
3169 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 3169 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
3170 Value* value = it.CurrentValue(); | 3170 Value* value = it.CurrentValue(); |
3171 value->definition()->AddEnvUse(value); | 3171 value->definition()->AddEnvUse(value); |
3172 } | 3172 } |
3173 } | 3173 } |
3174 | 3174 |
3175 | 3175 |
3176 // Copies the environment as outer on an inlined instruction and updates the | 3176 // Copies the environment as outer on an inlined instruction and updates the |
3177 // environment use lists. | 3177 // environment use lists. |
3178 void Environment::DeepCopyToOuter(Isolate* isolate, Instruction* instr) const { | 3178 void Environment::DeepCopyToOuter(Zone* zone, Instruction* instr) const { |
3179 // Create a deep copy removing caller arguments from the environment. | 3179 // Create a deep copy removing caller arguments from the environment. |
3180 ASSERT(this != NULL); | 3180 ASSERT(this != NULL); |
3181 ASSERT(instr->env()->outer() == NULL); | 3181 ASSERT(instr->env()->outer() == NULL); |
3182 intptr_t argument_count = instr->env()->fixed_parameter_count(); | 3182 intptr_t argument_count = instr->env()->fixed_parameter_count(); |
3183 Environment* copy = DeepCopy(isolate, values_.length() - argument_count); | 3183 Environment* copy = DeepCopy(zone, values_.length() - argument_count); |
3184 instr->env()->outer_ = copy; | 3184 instr->env()->outer_ = copy; |
3185 intptr_t use_index = instr->env()->Length(); // Start index after inner. | 3185 intptr_t use_index = instr->env()->Length(); // Start index after inner. |
3186 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 3186 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
3187 Value* value = it.CurrentValue(); | 3187 Value* value = it.CurrentValue(); |
3188 value->set_instruction(instr); | 3188 value->set_instruction(instr); |
3189 value->set_use_index(use_index++); | 3189 value->set_use_index(use_index++); |
3190 value->definition()->AddEnvUse(value); | 3190 value->definition()->AddEnvUse(value); |
3191 } | 3191 } |
3192 } | 3192 } |
3193 | 3193 |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3587 case Token::kTRUNCDIV: return 0; | 3587 case Token::kTRUNCDIV: return 0; |
3588 case Token::kMOD: return 1; | 3588 case Token::kMOD: return 1; |
3589 default: UNIMPLEMENTED(); return -1; | 3589 default: UNIMPLEMENTED(); return -1; |
3590 } | 3590 } |
3591 } | 3591 } |
3592 | 3592 |
3593 | 3593 |
3594 #undef __ | 3594 #undef __ |
3595 | 3595 |
3596 } // namespace dart | 3596 } // namespace dart |
OLD | NEW |