| 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 |