| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 7 #if defined(TARGET_ARCH_ARM) | 7 #if defined(TARGET_ARCH_ARM) |
| 8 | 8 |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 | 10 |
| (...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 | 1927 |
| 1928 | 1928 |
| 1929 class BoxAllocationSlowPath : public SlowPathCode { | 1929 class BoxAllocationSlowPath : public SlowPathCode { |
| 1930 public: | 1930 public: |
| 1931 BoxAllocationSlowPath(Instruction* instruction, | 1931 BoxAllocationSlowPath(Instruction* instruction, |
| 1932 const Class& cls, | 1932 const Class& cls, |
| 1933 Register result) | 1933 Register result) |
| 1934 : instruction_(instruction), cls_(cls), result_(result) {} | 1934 : instruction_(instruction), cls_(cls), result_(result) {} |
| 1935 | 1935 |
| 1936 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1936 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1937 compiler->SpecialStatsBegin( |
| 1938 CombinedCodeStatistics::kTagBoxAllocationSlowPath); |
| 1937 if (Assembler::EmittingComments()) { | 1939 if (Assembler::EmittingComments()) { |
| 1938 __ Comment("%s slow path allocation of %s", instruction_->DebugName(), | 1940 __ Comment("%s slow path allocation of %s", instruction_->DebugName(), |
| 1939 String::Handle(cls_.ScrubbedName()).ToCString()); | 1941 String::Handle(cls_.ScrubbedName()).ToCString()); |
| 1940 } | 1942 } |
| 1941 __ Bind(entry_label()); | 1943 __ Bind(entry_label()); |
| 1942 const Code& stub = Code::ZoneHandle( | 1944 const Code& stub = Code::ZoneHandle( |
| 1943 compiler->zone(), StubCode::GetAllocationStubForClass(cls_)); | 1945 compiler->zone(), StubCode::GetAllocationStubForClass(cls_)); |
| 1944 const StubEntry stub_entry(stub); | 1946 const StubEntry stub_entry(stub); |
| 1945 | 1947 |
| 1946 LocationSummary* locs = instruction_->locs(); | 1948 LocationSummary* locs = instruction_->locs(); |
| 1947 | 1949 |
| 1948 locs->live_registers()->Remove(Location::RegisterLocation(result_)); | 1950 locs->live_registers()->Remove(Location::RegisterLocation(result_)); |
| 1949 | 1951 |
| 1950 compiler->SaveLiveRegisters(locs); | 1952 compiler->SaveLiveRegisters(locs); |
| 1951 compiler->GenerateCall(TokenPosition::kNoSource, // No token position. | 1953 compiler->GenerateCall(TokenPosition::kNoSource, // No token position. |
| 1952 stub_entry, RawPcDescriptors::kOther, locs); | 1954 stub_entry, RawPcDescriptors::kOther, locs); |
| 1953 compiler->AddStubCallTarget(stub); | 1955 compiler->AddStubCallTarget(stub); |
| 1954 __ MoveRegister(result_, R0); | 1956 __ MoveRegister(result_, R0); |
| 1955 compiler->RestoreLiveRegisters(locs); | 1957 compiler->RestoreLiveRegisters(locs); |
| 1956 __ b(exit_label()); | 1958 __ b(exit_label()); |
| 1959 compiler->SpecialStatsEnd( |
| 1960 CombinedCodeStatistics::kTagBoxAllocationSlowPath); |
| 1957 } | 1961 } |
| 1958 | 1962 |
| 1959 static void Allocate(FlowGraphCompiler* compiler, | 1963 static void Allocate(FlowGraphCompiler* compiler, |
| 1960 Instruction* instruction, | 1964 Instruction* instruction, |
| 1961 const Class& cls, | 1965 const Class& cls, |
| 1962 Register result, | 1966 Register result, |
| 1963 Register temp) { | 1967 Register temp) { |
| 1964 if (compiler->intrinsic_mode()) { | 1968 if (compiler->intrinsic_mode()) { |
| 1965 __ TryAllocate(cls, compiler->intrinsic_slow_path_label(), result, temp); | 1969 __ TryAllocate(cls, compiler->intrinsic_slow_path_label(), result, temp); |
| 1966 } else { | 1970 } else { |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2727 } | 2731 } |
| 2728 | 2732 |
| 2729 | 2733 |
| 2730 class AllocateContextSlowPath : public SlowPathCode { | 2734 class AllocateContextSlowPath : public SlowPathCode { |
| 2731 public: | 2735 public: |
| 2732 explicit AllocateContextSlowPath( | 2736 explicit AllocateContextSlowPath( |
| 2733 AllocateUninitializedContextInstr* instruction) | 2737 AllocateUninitializedContextInstr* instruction) |
| 2734 : instruction_(instruction) {} | 2738 : instruction_(instruction) {} |
| 2735 | 2739 |
| 2736 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2740 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2741 compiler->SpecialStatsBegin( |
| 2742 CombinedCodeStatistics::kTagAllocateContextSlowPath); |
| 2737 __ Comment("AllocateContextSlowPath"); | 2743 __ Comment("AllocateContextSlowPath"); |
| 2738 __ Bind(entry_label()); | 2744 __ Bind(entry_label()); |
| 2739 | 2745 |
| 2740 LocationSummary* locs = instruction_->locs(); | 2746 LocationSummary* locs = instruction_->locs(); |
| 2741 locs->live_registers()->Remove(locs->out(0)); | 2747 locs->live_registers()->Remove(locs->out(0)); |
| 2742 | 2748 |
| 2743 compiler->SaveLiveRegisters(locs); | 2749 compiler->SaveLiveRegisters(locs); |
| 2744 | 2750 |
| 2745 __ LoadImmediate(R1, instruction_->num_context_variables()); | 2751 __ LoadImmediate(R1, instruction_->num_context_variables()); |
| 2746 const Code& stub = Code::ZoneHandle( | 2752 const Code& stub = Code::ZoneHandle( |
| 2747 compiler->zone(), StubCode::AllocateContext_entry()->code()); | 2753 compiler->zone(), StubCode::AllocateContext_entry()->code()); |
| 2748 compiler->AddStubCallTarget(stub); | 2754 compiler->AddStubCallTarget(stub); |
| 2749 compiler->GenerateCall(instruction_->token_pos(), | 2755 compiler->GenerateCall(instruction_->token_pos(), |
| 2750 *StubCode::AllocateContext_entry(), | 2756 *StubCode::AllocateContext_entry(), |
| 2751 RawPcDescriptors::kOther, locs); | 2757 RawPcDescriptors::kOther, locs); |
| 2752 ASSERT(instruction_->locs()->out(0).reg() == R0); | 2758 ASSERT(instruction_->locs()->out(0).reg() == R0); |
| 2753 compiler->RestoreLiveRegisters(instruction_->locs()); | 2759 compiler->RestoreLiveRegisters(instruction_->locs()); |
| 2754 __ b(exit_label()); | 2760 __ b(exit_label()); |
| 2761 compiler->SpecialStatsEnd( |
| 2762 CombinedCodeStatistics::kTagAllocateContextSlowPath); |
| 2755 } | 2763 } |
| 2756 | 2764 |
| 2757 private: | 2765 private: |
| 2758 AllocateUninitializedContextInstr* instruction_; | 2766 AllocateUninitializedContextInstr* instruction_; |
| 2759 }; | 2767 }; |
| 2760 | 2768 |
| 2761 | 2769 |
| 2762 void AllocateUninitializedContextInstr::EmitNativeCode( | 2770 void AllocateUninitializedContextInstr::EmitNativeCode( |
| 2763 FlowGraphCompiler* compiler) { | 2771 FlowGraphCompiler* compiler) { |
| 2764 Register temp0 = locs()->temp(0).reg(); | 2772 Register temp0 = locs()->temp(0).reg(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2941 return summary; | 2949 return summary; |
| 2942 } | 2950 } |
| 2943 | 2951 |
| 2944 | 2952 |
| 2945 class CheckStackOverflowSlowPath : public SlowPathCode { | 2953 class CheckStackOverflowSlowPath : public SlowPathCode { |
| 2946 public: | 2954 public: |
| 2947 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 2955 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) |
| 2948 : instruction_(instruction) {} | 2956 : instruction_(instruction) {} |
| 2949 | 2957 |
| 2950 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2958 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2959 compiler->SpecialStatsBegin( |
| 2960 CombinedCodeStatistics::kTagCheckStackOverflowSlowPath); |
| 2951 if (FLAG_use_osr && osr_entry_label()->IsLinked()) { | 2961 if (FLAG_use_osr && osr_entry_label()->IsLinked()) { |
| 2952 const Register value = instruction_->locs()->temp(0).reg(); | 2962 const Register value = instruction_->locs()->temp(0).reg(); |
| 2953 __ Comment("CheckStackOverflowSlowPathOsr"); | 2963 __ Comment("CheckStackOverflowSlowPathOsr"); |
| 2954 __ Bind(osr_entry_label()); | 2964 __ Bind(osr_entry_label()); |
| 2955 __ LoadImmediate(value, Thread::kOsrRequest); | 2965 __ LoadImmediate(value, Thread::kOsrRequest); |
| 2956 __ str(value, Address(THR, Thread::stack_overflow_flags_offset())); | 2966 __ str(value, Address(THR, Thread::stack_overflow_flags_offset())); |
| 2957 } | 2967 } |
| 2958 __ Comment("CheckStackOverflowSlowPath"); | 2968 __ Comment("CheckStackOverflowSlowPath"); |
| 2959 __ Bind(entry_label()); | 2969 __ Bind(entry_label()); |
| 2960 compiler->SaveLiveRegisters(instruction_->locs()); | 2970 compiler->SaveLiveRegisters(instruction_->locs()); |
| 2961 // pending_deoptimization_env_ is needed to generate a runtime call that | 2971 // pending_deoptimization_env_ is needed to generate a runtime call that |
| 2962 // may throw an exception. | 2972 // may throw an exception. |
| 2963 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2973 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
| 2964 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); | 2974 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); |
| 2965 compiler->pending_deoptimization_env_ = env; | 2975 compiler->pending_deoptimization_env_ = env; |
| 2966 compiler->GenerateRuntimeCall( | 2976 compiler->GenerateRuntimeCall( |
| 2967 instruction_->token_pos(), instruction_->deopt_id(), | 2977 instruction_->token_pos(), instruction_->deopt_id(), |
| 2968 kStackOverflowRuntimeEntry, 0, instruction_->locs()); | 2978 kStackOverflowRuntimeEntry, 0, instruction_->locs()); |
| 2969 | 2979 |
| 2970 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { | 2980 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
| 2971 // In unoptimized code, record loop stack checks as possible OSR entries. | 2981 // In unoptimized code, record loop stack checks as possible OSR entries. |
| 2972 compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry, | 2982 compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry, |
| 2973 instruction_->deopt_id(), | 2983 instruction_->deopt_id(), |
| 2974 TokenPosition::kNoSource); | 2984 TokenPosition::kNoSource); |
| 2975 } | 2985 } |
| 2976 compiler->pending_deoptimization_env_ = NULL; | 2986 compiler->pending_deoptimization_env_ = NULL; |
| 2977 compiler->RestoreLiveRegisters(instruction_->locs()); | 2987 compiler->RestoreLiveRegisters(instruction_->locs()); |
| 2978 __ b(exit_label()); | 2988 __ b(exit_label()); |
| 2989 compiler->SpecialStatsEnd( |
| 2990 CombinedCodeStatistics::kTagCheckStackOverflowSlowPath); |
| 2979 } | 2991 } |
| 2980 | 2992 |
| 2981 Label* osr_entry_label() { | 2993 Label* osr_entry_label() { |
| 2982 ASSERT(FLAG_use_osr); | 2994 ASSERT(FLAG_use_osr); |
| 2983 return &osr_entry_label_; | 2995 return &osr_entry_label_; |
| 2984 } | 2996 } |
| 2985 | 2997 |
| 2986 private: | 2998 private: |
| 2987 CheckStackOverflowInstr* instruction_; | 2999 CheckStackOverflowInstr* instruction_; |
| 2988 Label osr_entry_label_; | 3000 Label osr_entry_label_; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3109 } | 3121 } |
| 3110 } | 3122 } |
| 3111 | 3123 |
| 3112 | 3124 |
| 3113 class CheckedSmiSlowPath : public SlowPathCode { | 3125 class CheckedSmiSlowPath : public SlowPathCode { |
| 3114 public: | 3126 public: |
| 3115 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index) | 3127 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index) |
| 3116 : instruction_(instruction), try_index_(try_index) {} | 3128 : instruction_(instruction), try_index_(try_index) {} |
| 3117 | 3129 |
| 3118 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 3130 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3131 compiler->SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedSmiSlowPath); |
| 3119 if (Assembler::EmittingComments()) { | 3132 if (Assembler::EmittingComments()) { |
| 3120 __ Comment("slow path smi operation"); | 3133 __ Comment("slow path smi operation"); |
| 3121 } | 3134 } |
| 3122 __ Bind(entry_label()); | 3135 __ Bind(entry_label()); |
| 3123 LocationSummary* locs = instruction_->locs(); | 3136 LocationSummary* locs = instruction_->locs(); |
| 3124 Register result = locs->out(0).reg(); | 3137 Register result = locs->out(0).reg(); |
| 3125 locs->live_registers()->Remove(Location::RegisterLocation(result)); | 3138 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 3126 | 3139 |
| 3127 compiler->SaveLiveRegisters(locs); | 3140 compiler->SaveLiveRegisters(locs); |
| 3128 __ Push(locs->in(0).reg()); | 3141 __ Push(locs->in(0).reg()); |
| 3129 __ Push(locs->in(1).reg()); | 3142 __ Push(locs->in(1).reg()); |
| 3130 compiler->EmitMegamorphicInstanceCall( | 3143 compiler->EmitMegamorphicInstanceCall( |
| 3131 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), | 3144 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), |
| 3132 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), | 3145 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), |
| 3133 locs, try_index_, | 3146 locs, try_index_, |
| 3134 /* slow_path_argument_count = */ 2); | 3147 /* slow_path_argument_count = */ 2); |
| 3135 __ mov(result, Operand(R0)); | 3148 __ mov(result, Operand(R0)); |
| 3136 compiler->RestoreLiveRegisters(locs); | 3149 compiler->RestoreLiveRegisters(locs); |
| 3137 __ b(exit_label()); | 3150 __ b(exit_label()); |
| 3151 compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedSmiSlowPath); |
| 3138 } | 3152 } |
| 3139 | 3153 |
| 3140 private: | 3154 private: |
| 3141 CheckedSmiOpInstr* instruction_; | 3155 CheckedSmiOpInstr* instruction_; |
| 3142 intptr_t try_index_; | 3156 intptr_t try_index_; |
| 3143 }; | 3157 }; |
| 3144 | 3158 |
| 3145 | 3159 |
| 3146 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, | 3160 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, |
| 3147 bool opt) const { | 3161 bool opt) const { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3243 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, | 3257 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, |
| 3244 intptr_t try_index, | 3258 intptr_t try_index, |
| 3245 BranchLabels labels, | 3259 BranchLabels labels, |
| 3246 bool merged) | 3260 bool merged) |
| 3247 : instruction_(instruction), | 3261 : instruction_(instruction), |
| 3248 try_index_(try_index), | 3262 try_index_(try_index), |
| 3249 labels_(labels), | 3263 labels_(labels), |
| 3250 merged_(merged) {} | 3264 merged_(merged) {} |
| 3251 | 3265 |
| 3252 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 3266 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3267 compiler->SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedSmiCmpSlowPat
h); |
| 3253 if (Assembler::EmittingComments()) { | 3268 if (Assembler::EmittingComments()) { |
| 3254 __ Comment("slow path smi operation"); | 3269 __ Comment("slow path smi operation"); |
| 3255 } | 3270 } |
| 3256 __ Bind(entry_label()); | 3271 __ Bind(entry_label()); |
| 3257 LocationSummary* locs = instruction_->locs(); | 3272 LocationSummary* locs = instruction_->locs(); |
| 3258 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); | 3273 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); |
| 3259 locs->live_registers()->Remove(Location::RegisterLocation(result)); | 3274 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 3260 | 3275 |
| 3261 compiler->SaveLiveRegisters(locs); | 3276 compiler->SaveLiveRegisters(locs); |
| 3262 __ Push(locs->in(0).reg()); | 3277 __ Push(locs->in(0).reg()); |
| 3263 __ Push(locs->in(1).reg()); | 3278 __ Push(locs->in(1).reg()); |
| 3264 compiler->EmitMegamorphicInstanceCall( | 3279 compiler->EmitMegamorphicInstanceCall( |
| 3265 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), | 3280 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), |
| 3266 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), | 3281 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), |
| 3267 locs, try_index_, | 3282 locs, try_index_, |
| 3268 /* slow_path_argument_count = */ 2); | 3283 /* slow_path_argument_count = */ 2); |
| 3269 __ mov(result, Operand(R0)); | 3284 __ mov(result, Operand(R0)); |
| 3270 compiler->RestoreLiveRegisters(locs); | 3285 compiler->RestoreLiveRegisters(locs); |
| 3271 if (merged_) { | 3286 if (merged_) { |
| 3272 __ CompareObject(result, Bool::True()); | 3287 __ CompareObject(result, Bool::True()); |
| 3273 __ b( | 3288 __ b( |
| 3274 instruction_->is_negated() ? labels_.false_label : labels_.true_label, | 3289 instruction_->is_negated() ? labels_.false_label : labels_.true_label, |
| 3275 EQ); | 3290 EQ); |
| 3276 __ b(instruction_->is_negated() ? labels_.true_label | 3291 __ b(instruction_->is_negated() ? labels_.true_label |
| 3277 : labels_.false_label); | 3292 : labels_.false_label); |
| 3278 } else { | 3293 } else { |
| 3279 __ b(exit_label()); | 3294 __ b(exit_label()); |
| 3280 } | 3295 } |
| 3296 compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedSmiCmpSlowPath)
; |
| 3281 } | 3297 } |
| 3282 | 3298 |
| 3283 private: | 3299 private: |
| 3284 CheckedSmiComparisonInstr* instruction_; | 3300 CheckedSmiComparisonInstr* instruction_; |
| 3285 intptr_t try_index_; | 3301 intptr_t try_index_; |
| 3286 BranchLabels labels_; | 3302 BranchLabels labels_; |
| 3287 bool merged_; | 3303 bool merged_; |
| 3288 }; | 3304 }; |
| 3289 | 3305 |
| 3290 | 3306 |
| (...skipping 3936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7227 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 7243 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
| 7228 kGrowRegExpStackRuntimeEntry, 1, locs()); | 7244 kGrowRegExpStackRuntimeEntry, 1, locs()); |
| 7229 __ Drop(1); | 7245 __ Drop(1); |
| 7230 __ Pop(result); | 7246 __ Pop(result); |
| 7231 } | 7247 } |
| 7232 | 7248 |
| 7233 | 7249 |
| 7234 } // namespace dart | 7250 } // namespace dart |
| 7235 | 7251 |
| 7236 #endif // defined TARGET_ARCH_ARM | 7252 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |