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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 2030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 #else // !DBC | 2041 #else // !DBC |
2042 if (frame->IsMarkedForLazyDeopt()) { | 2042 if (frame->IsMarkedForLazyDeopt()) { |
2043 // Deopt already scheduled. | 2043 // Deopt already scheduled. |
2044 if (FLAG_trace_deoptimization) { | 2044 if (FLAG_trace_deoptimization) { |
2045 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp()); | 2045 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp()); |
2046 } | 2046 } |
2047 } else { | 2047 } else { |
2048 uword deopt_pc = frame->pc(); | 2048 uword deopt_pc = frame->pc(); |
2049 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); | 2049 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); |
2050 | 2050 |
2051 // N.B.: Update the pending deopt table before updating the frame. The | |
2052 // profiler may attempt a stack walk in between. | |
2053 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = | |
2054 thread->isolate()->pending_deopts(); | |
2055 for (intptr_t i = 0; i < pending_deopts->length(); i++) { | |
2056 ASSERT((*pending_deopts)[i].fp() != frame->fp()); | |
2057 } | |
2058 PendingLazyDeopt pair(frame->fp(), deopt_pc); | |
2059 pending_deopts->Add(pair); | |
2060 | |
2061 #if defined(DEBUG) | 2051 #if defined(DEBUG) |
2062 ValidateFrames(); | 2052 ValidateFrames(); |
2063 #endif | 2053 #endif |
2064 | 2054 |
| 2055 // N.B.: Update the pending deopt table before updating the frame. The |
| 2056 // profiler may attempt a stack walk in between. |
| 2057 thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc); |
2065 frame->MarkForLazyDeopt(); | 2058 frame->MarkForLazyDeopt(); |
2066 | 2059 |
2067 if (FLAG_trace_deoptimization) { | 2060 if (FLAG_trace_deoptimization) { |
2068 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", | 2061 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", |
2069 frame->fp(), deopt_pc); | 2062 frame->fp(), deopt_pc); |
2070 } | 2063 } |
2071 } | 2064 } |
2072 #endif // !DBC | 2065 #endif // !DBC |
2073 | 2066 |
2074 // Mark code as dead (do not GC its embedded objects). | 2067 // Mark code as dead (do not GC its embedded objects). |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 if (FLAG_trace_deoptimization) { | 2154 if (FLAG_trace_deoptimization) { |
2162 const Function& function = Function::Handle(optimized_code.function()); | 2155 const Function& function = Function::Handle(optimized_code.function()); |
2163 THR_Print("== Deoptimizing code for '%s', %s, %s\n", | 2156 THR_Print("== Deoptimizing code for '%s', %s, %s\n", |
2164 function.ToFullyQualifiedCString(), | 2157 function.ToFullyQualifiedCString(), |
2165 deoptimizing_code ? "code & frame" : "frame", | 2158 deoptimizing_code ? "code & frame" : "frame", |
2166 is_lazy_deopt ? "lazy-deopt" : ""); | 2159 is_lazy_deopt ? "lazy-deopt" : ""); |
2167 } | 2160 } |
2168 | 2161 |
2169 #if !defined(TARGET_ARCH_DBC) | 2162 #if !defined(TARGET_ARCH_DBC) |
2170 if (is_lazy_deopt) { | 2163 if (is_lazy_deopt) { |
2171 uword deopt_pc = 0; | 2164 uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp()); |
2172 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = | |
2173 isolate->pending_deopts(); | |
2174 for (intptr_t i = 0; i < pending_deopts->length(); i++) { | |
2175 if ((*pending_deopts)[i].fp() == caller_frame->fp()) { | |
2176 deopt_pc = (*pending_deopts)[i].pc(); | |
2177 break; | |
2178 } | |
2179 } | |
2180 #if defined(DEBUG) | |
2181 // Check for conflicting entries. | |
2182 for (intptr_t i = 0; i < pending_deopts->length(); i++) { | |
2183 if ((*pending_deopts)[i].fp() == caller_frame->fp()) { | |
2184 ASSERT((*pending_deopts)[i].pc() == deopt_pc); | |
2185 } | |
2186 } | |
2187 #endif | |
2188 if (FLAG_trace_deoptimization) { | 2165 if (FLAG_trace_deoptimization) { |
2189 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", | 2166 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", |
2190 caller_frame->fp(), deopt_pc); | 2167 caller_frame->fp(), deopt_pc); |
2191 } | 2168 } |
2192 ASSERT(deopt_pc != 0); | |
2193 | 2169 |
2194 // N.B.: Update frame before updating pending deopt table. The profiler | 2170 // N.B.: Update frame before updating pending deopt table. The profiler |
2195 // may attempt a stack walk in between. | 2171 // may attempt a stack walk in between. |
2196 caller_frame->set_pc(deopt_pc); | 2172 caller_frame->set_pc(deopt_pc); |
2197 ASSERT(caller_frame->pc() == deopt_pc); | 2173 ASSERT(caller_frame->pc() == deopt_pc); |
2198 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc())); | 2174 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc())); |
2199 | 2175 isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp()); |
2200 for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) { | |
2201 if ((*pending_deopts)[i].fp() <= caller_frame->fp()) { | |
2202 pending_deopts->RemoveAt(i); | |
2203 } | |
2204 } | |
2205 } else { | 2176 } else { |
2206 if (FLAG_trace_deoptimization) { | 2177 if (FLAG_trace_deoptimization) { |
2207 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", | 2178 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", |
2208 caller_frame->fp(), caller_frame->pc()); | 2179 caller_frame->fp(), caller_frame->pc()); |
2209 } | 2180 } |
2210 } | 2181 } |
2211 #endif // !DBC | 2182 #endif // !DBC |
2212 | 2183 |
2213 // Copy the saved registers from the stack. | 2184 // Copy the saved registers from the stack. |
2214 fpu_register_t* fpu_registers; | 2185 fpu_register_t* fpu_registers; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2373 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 2344 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
2374 const TypedData& new_data = | 2345 const TypedData& new_data = |
2375 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 2346 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
2376 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 2347 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
2377 typed_data_cell.SetAt(0, new_data); | 2348 typed_data_cell.SetAt(0, new_data); |
2378 arguments.SetReturn(new_data); | 2349 arguments.SetReturn(new_data); |
2379 } | 2350 } |
2380 | 2351 |
2381 | 2352 |
2382 } // namespace dart | 2353 } // namespace dart |
OLD | NEW |