Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: runtime/vm/code_generator.cc

Issue 2396433003: Lazy deopt: (Closed)
Patch Set: . Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/exceptions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 for (intptr_t i = 0; i < handlers.num_entries(); ++i) { 2032 for (intptr_t i = 0; i < handlers.num_entries(); ++i) {
2033 handlers.GetHandlerInfo(i, &info); 2033 handlers.GetHandlerInfo(i, &info);
2034 const uword patch_pc = instrs.PayloadStart() + info.handler_pc_offset; 2034 const uword patch_pc = instrs.PayloadStart() + info.handler_pc_offset;
2035 CodePatcher::InsertDeoptimizationCallAt(patch_pc); 2035 CodePatcher::InsertDeoptimizationCallAt(patch_pc);
2036 if (FLAG_trace_patching) { 2036 if (FLAG_trace_patching) {
2037 OS::PrintErr(" at handler 0x%" Px "\n", patch_pc); 2037 OS::PrintErr(" at handler 0x%" Px "\n", patch_pc);
2038 } 2038 }
2039 } 2039 }
2040 } 2040 }
2041 #else // !DBC 2041 #else // !DBC
2042 uword lazy_deopt_entry = 2042 if (frame->IsMarkedForLazyDeopt()) {
2043 StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint();
2044 if (frame->pc() == lazy_deopt_entry) {
2045 // Deopt already scheduled. 2043 // Deopt already scheduled.
2046 if (FLAG_trace_deoptimization) { 2044 if (FLAG_trace_deoptimization) {
2047 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());
2048 } 2046 }
2049 } else { 2047 } else {
2050 uword deopt_pc = frame->pc(); 2048 uword deopt_pc = frame->pc();
2051 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); 2049 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc));
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 }
2052 PendingLazyDeopt pair(frame->fp(), deopt_pc); 2058 PendingLazyDeopt pair(frame->fp(), deopt_pc);
2053 thread->isolate()->pending_deopts()->Add(pair); 2059 pending_deopts->Add(pair);
2054 frame->set_pc(lazy_deopt_entry); 2060
2061 #if defined(DEBUG)
2062 ValidateFrames();
2063 #endif
2064
2065 frame->MarkForLazyDeopt();
2055 2066
2056 if (FLAG_trace_deoptimization) { 2067 if (FLAG_trace_deoptimization) {
2057 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", 2068 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n",
2058 frame->fp(), deopt_pc); 2069 frame->fp(), deopt_pc);
2059 } 2070 }
2060 } 2071 }
2061 #endif // !DBC 2072 #endif // !DBC
2062 2073
2063 // Mark code as dead (do not GC its embedded objects). 2074 // Mark code as dead (do not GC its embedded objects).
2064 optimized_code.set_is_alive(false); 2075 optimized_code.set_is_alive(false);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 function.ToFullyQualifiedCString(), 2164 function.ToFullyQualifiedCString(),
2154 deoptimizing_code ? "code & frame" : "frame", 2165 deoptimizing_code ? "code & frame" : "frame",
2155 is_lazy_deopt ? "lazy-deopt" : ""); 2166 is_lazy_deopt ? "lazy-deopt" : "");
2156 } 2167 }
2157 2168
2158 #if !defined(TARGET_ARCH_DBC) 2169 #if !defined(TARGET_ARCH_DBC)
2159 if (is_lazy_deopt) { 2170 if (is_lazy_deopt) {
2160 uword deopt_pc = 0; 2171 uword deopt_pc = 0;
2161 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = 2172 MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
2162 isolate->pending_deopts(); 2173 isolate->pending_deopts();
2163 for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) { 2174 for (intptr_t i = 0; i < pending_deopts->length(); i++) {
2164 if ((*pending_deopts)[i].fp() == caller_frame->fp()) { 2175 if ((*pending_deopts)[i].fp() == caller_frame->fp()) {
2165 deopt_pc = (*pending_deopts)[i].pc(); 2176 deopt_pc = (*pending_deopts)[i].pc();
2166 break; 2177 break;
2167 } 2178 }
2168 } 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) {
2189 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n",
2190 caller_frame->fp(), deopt_pc);
2191 }
2192 ASSERT(deopt_pc != 0);
2193
2194 // N.B.: Update frame before updating pending deopt table. The profiler
2195 // may attempt a stack walk in between.
2196 caller_frame->set_pc(deopt_pc);
2197 ASSERT(caller_frame->pc() == deopt_pc);
2198 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc()));
2199
2169 for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) { 2200 for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) {
2170 if ((*pending_deopts)[i].fp() <= caller_frame->fp()) { 2201 if ((*pending_deopts)[i].fp() <= caller_frame->fp()) {
2171 pending_deopts->RemoveAt(i); 2202 pending_deopts->RemoveAt(i);
2172 } 2203 }
2173 } 2204 }
2174 if (FLAG_trace_deoptimization) {
2175 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n",
2176 caller_frame->fp(), deopt_pc);
2177 THR_Print("%" Pd " pending lazy deopts\n",
2178 pending_deopts->length());
2179 }
2180 ASSERT(deopt_pc != 0);
2181 caller_frame->set_pc(deopt_pc);
2182 ASSERT(caller_frame->pc() == deopt_pc);
2183 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc()));
2184 } else { 2205 } else {
2185 if (FLAG_trace_deoptimization) { 2206 if (FLAG_trace_deoptimization) {
2186 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", 2207 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n",
2187 caller_frame->fp(), caller_frame->pc()); 2208 caller_frame->fp(), caller_frame->pc());
2188 } 2209 }
2189 } 2210 }
2190 #endif // !DBC 2211 #endif // !DBC
2191 2212
2192 // Copy the saved registers from the stack. 2213 // Copy the saved registers from the stack.
2193 fpu_register_t* fpu_registers; 2214 fpu_register_t* fpu_registers;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 // Returns number of bytes to remove from the expression stack of the 2282 // Returns number of bytes to remove from the expression stack of the
2262 // bottom-most deoptimized frame. Those arguments were artificially injected 2283 // bottom-most deoptimized frame. Those arguments were artificially injected
2263 // under return address to keep them discoverable by GC that can occur during 2284 // under return address to keep them discoverable by GC that can occur during
2264 // materialization phase. 2285 // materialization phase.
2265 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) { 2286 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
2266 #if !defined(DART_PRECOMPILED_RUNTIME) 2287 #if !defined(DART_PRECOMPILED_RUNTIME)
2267 #if defined(DEBUG) 2288 #if defined(DEBUG)
2268 { 2289 {
2269 // We may rendezvous for a safepoint at entry or GC from the allocations 2290 // We may rendezvous for a safepoint at entry or GC from the allocations
2270 // below. Check the stack is walkable. 2291 // below. Check the stack is walkable.
2271 StackFrameIterator frames_iterator(StackFrameIterator::kValidateFrames); 2292 ValidateFrames();
2272 StackFrame* frame = frames_iterator.NextFrame();
2273 while (frame != NULL) {
2274 frame = frames_iterator.NextFrame();
2275 }
2276 } 2293 }
2277 #endif 2294 #endif
2278 DeoptContext* deopt_context = isolate->deopt_context(); 2295 DeoptContext* deopt_context = isolate->deopt_context();
2279 intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects(); 2296 intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects();
2280 isolate->set_deopt_context(NULL); 2297 isolate->set_deopt_context(NULL);
2281 delete deopt_context; 2298 delete deopt_context;
2282 2299
2283 // Return value tells deoptimization stub to remove the given number of bytes 2300 // Return value tells deoptimization stub to remove the given number of bytes
2284 // from the stack. 2301 // from the stack.
2285 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize))); 2302 arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize)));
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2373 const intptr_t elm_size = old_data.ElementSizeInBytes();
2357 const TypedData& new_data = 2374 const TypedData& new_data =
2358 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2375 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2359 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2376 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2360 typed_data_cell.SetAt(0, new_data); 2377 typed_data_cell.SetAt(0, new_data);
2361 arguments.SetReturn(new_data); 2378 arguments.SetReturn(new_data);
2362 } 2379 }
2363 2380
2364 2381
2365 } // namespace dart 2382 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/exceptions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698