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