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

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

Issue 2741553002: Do not rely on code patching on DBC for lazy deoptimization. (Closed)
Patch Set: Cleanups Created 3 years, 9 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/code_patcher.h » ('j') | runtime/vm/code_patcher.h » ('J')
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 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 Exceptions::PropagateError(error); 1928 Exceptions::PropagateError(error);
1929 } 1929 }
1930 const Code& unoptimized_code = 1930 const Code& unoptimized_code =
1931 Code::Handle(zone, function.unoptimized_code()); 1931 Code::Handle(zone, function.unoptimized_code());
1932 ASSERT(!unoptimized_code.IsNull()); 1932 ASSERT(!unoptimized_code.IsNull());
1933 // The switch to unoptimized code may have already occurred. 1933 // The switch to unoptimized code may have already occurred.
1934 if (function.HasOptimizedCode()) { 1934 if (function.HasOptimizedCode()) {
1935 function.SwitchToUnoptimizedCode(); 1935 function.SwitchToUnoptimizedCode();
1936 } 1936 }
1937 1937
1938 #if defined(TARGET_ARCH_DBC)
1939 const Instructions& instrs =
1940 Instructions::Handle(zone, optimized_code.instructions());
1941 {
1942 WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
1943 CodePatcher::InsertDeoptimizationCallAt(frame->pc());
1944 if (FLAG_trace_patching) {
1945 const String& name = String::Handle(function.name());
1946 OS::PrintErr("InsertDeoptimizationCallAt: 0x%" Px " for %s\n",
1947 frame->pc(), name.ToCString());
1948 }
1949 const ExceptionHandlers& handlers =
1950 ExceptionHandlers::Handle(zone, optimized_code.exception_handlers());
1951 ExceptionHandlerInfo info;
1952 for (intptr_t i = 0; i < handlers.num_entries(); ++i) {
1953 handlers.GetHandlerInfo(i, &info);
1954 const uword patch_pc = instrs.PayloadStart() + info.handler_pc_offset;
1955 CodePatcher::InsertDeoptimizationCallAt(patch_pc);
1956 if (FLAG_trace_patching) {
1957 OS::PrintErr(" at handler 0x%" Px "\n", patch_pc);
1958 }
1959 }
1960 }
1961 #else // !DBC
1962 if (frame->IsMarkedForLazyDeopt()) { 1938 if (frame->IsMarkedForLazyDeopt()) {
1963 // Deopt already scheduled. 1939 // Deopt already scheduled.
1964 if (FLAG_trace_deoptimization) { 1940 if (FLAG_trace_deoptimization) {
1965 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp()); 1941 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp());
1966 } 1942 }
1967 } else { 1943 } else {
1968 uword deopt_pc = frame->pc(); 1944 uword deopt_pc = frame->pc();
1969 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); 1945 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc));
1970 1946
1971 #if defined(DEBUG) 1947 #if defined(DEBUG)
1972 ValidateFrames(); 1948 ValidateFrames();
1973 #endif 1949 #endif
1974 1950
1975 // N.B.: Update the pending deopt table before updating the frame. The 1951 // N.B.: Update the pending deopt table before updating the frame. The
1976 // profiler may attempt a stack walk in between. 1952 // profiler may attempt a stack walk in between.
1977 thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc); 1953 thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc);
1978 frame->MarkForLazyDeopt(); 1954 frame->MarkForLazyDeopt();
1979 1955
1980 if (FLAG_trace_deoptimization) { 1956 if (FLAG_trace_deoptimization) {
1981 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", 1957 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n",
1982 frame->fp(), deopt_pc); 1958 frame->fp(), deopt_pc);
1983 } 1959 }
1984 } 1960 }
1985 #endif // !DBC
1986 1961
1987 // Mark code as dead (do not GC its embedded objects). 1962 // Mark code as dead (do not GC its embedded objects).
1988 optimized_code.set_is_alive(false); 1963 optimized_code.set_is_alive(false);
1989 } 1964 }
1990 1965
1991 1966
1992 // Currently checks only that all optimized frames have kDeoptIndex 1967 // Currently checks only that all optimized frames have kDeoptIndex
1993 // and unoptimized code has the kDeoptAfter. 1968 // and unoptimized code has the kDeoptAfter.
1994 void DeoptimizeFunctionsOnStack() { 1969 void DeoptimizeFunctionsOnStack() {
1995 DartFrameIterator iterator; 1970 DartFrameIterator iterator;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 Function::Handle(thread->zone(), optimized_code.function()); 2048 Function::Handle(thread->zone(), optimized_code.function());
2074 const bool deoptimizing_code = top_function.HasOptimizedCode(); 2049 const bool deoptimizing_code = top_function.HasOptimizedCode();
2075 if (FLAG_trace_deoptimization) { 2050 if (FLAG_trace_deoptimization) {
2076 const Function& function = Function::Handle(optimized_code.function()); 2051 const Function& function = Function::Handle(optimized_code.function());
2077 THR_Print("== Deoptimizing code for '%s', %s, %s\n", 2052 THR_Print("== Deoptimizing code for '%s', %s, %s\n",
2078 function.ToFullyQualifiedCString(), 2053 function.ToFullyQualifiedCString(),
2079 deoptimizing_code ? "code & frame" : "frame", 2054 deoptimizing_code ? "code & frame" : "frame",
2080 is_lazy_deopt ? "lazy-deopt" : ""); 2055 is_lazy_deopt ? "lazy-deopt" : "");
2081 } 2056 }
2082 2057
2083 #if !defined(TARGET_ARCH_DBC)
2084 if (is_lazy_deopt) { 2058 if (is_lazy_deopt) {
2085 uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp()); 2059 uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp());
2086 if (FLAG_trace_deoptimization) { 2060 if (FLAG_trace_deoptimization) {
2087 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), 2061 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(),
2088 deopt_pc); 2062 deopt_pc);
2089 } 2063 }
2090 2064
2091 // N.B.: Update frame before updating pending deopt table. The profiler 2065 // N.B.: Update frame before updating pending deopt table. The profiler
2092 // may attempt a stack walk in between. 2066 // may attempt a stack walk in between.
2093 caller_frame->set_pc(deopt_pc); 2067 caller_frame->set_pc(deopt_pc);
2068 ASSERT(!caller_frame->IsMarkedForLazyDeopt());
2094 ASSERT(caller_frame->pc() == deopt_pc); 2069 ASSERT(caller_frame->pc() == deopt_pc);
2095 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc())); 2070 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc()));
2096 isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp()); 2071 isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp());
2097 } else { 2072 } else {
2098 if (FLAG_trace_deoptimization) { 2073 if (FLAG_trace_deoptimization) {
2099 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), 2074 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(),
2100 caller_frame->pc()); 2075 caller_frame->pc());
2101 } 2076 }
2102 } 2077 }
2103 #endif // !DBC
2104 2078
2105 // Copy the saved registers from the stack. 2079 // Copy the saved registers from the stack.
2106 fpu_register_t* fpu_registers; 2080 fpu_register_t* fpu_registers;
2107 intptr_t* cpu_registers; 2081 intptr_t* cpu_registers;
2108 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers); 2082 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
2109 2083
2110 // Create the DeoptContext. 2084 // Create the DeoptContext.
2111 DeoptContext* deopt_context = new DeoptContext( 2085 DeoptContext* deopt_context = new DeoptContext(
2112 caller_frame, optimized_code, DeoptContext::kDestIsOriginalFrame, 2086 caller_frame, optimized_code, DeoptContext::kDestIsOriginalFrame,
2113 fpu_registers, cpu_registers, is_lazy_deopt != 0, deoptimizing_code); 2087 fpu_registers, cpu_registers, is_lazy_deopt != 0, deoptimizing_code);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2235 const intptr_t elm_size = old_data.ElementSizeInBytes();
2262 const TypedData& new_data = 2236 const TypedData& new_data =
2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2237 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2238 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2265 typed_data_cell.SetAt(0, new_data); 2239 typed_data_cell.SetAt(0, new_data);
2266 arguments.SetReturn(new_data); 2240 arguments.SetReturn(new_data);
2267 } 2241 }
2268 2242
2269 2243
2270 } // namespace dart 2244 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_patcher.h » ('j') | runtime/vm/code_patcher.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698