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 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |