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 |
1938 if (frame->IsMarkedForLazyDeopt()) { | 1962 if (frame->IsMarkedForLazyDeopt()) { |
1939 // Deopt already scheduled. | 1963 // Deopt already scheduled. |
1940 if (FLAG_trace_deoptimization) { | 1964 if (FLAG_trace_deoptimization) { |
1941 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp()); | 1965 THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp()); |
1942 } | 1966 } |
1943 } else { | 1967 } else { |
1944 uword deopt_pc = frame->pc(); | 1968 uword deopt_pc = frame->pc(); |
1945 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); | 1969 ASSERT(optimized_code.ContainsInstructionAt(deopt_pc)); |
1946 | 1970 |
1947 #if defined(DEBUG) | 1971 #if defined(DEBUG) |
1948 ValidateFrames(); | 1972 ValidateFrames(); |
1949 #endif | 1973 #endif |
1950 | 1974 |
1951 // N.B.: Update the pending deopt table before updating the frame. The | 1975 // N.B.: Update the pending deopt table before updating the frame. The |
1952 // profiler may attempt a stack walk in between. | 1976 // profiler may attempt a stack walk in between. |
1953 thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc); | 1977 thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc); |
1954 frame->MarkForLazyDeopt(); | 1978 frame->MarkForLazyDeopt(); |
1955 | 1979 |
1956 if (FLAG_trace_deoptimization) { | 1980 if (FLAG_trace_deoptimization) { |
1957 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", | 1981 THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n", |
1958 frame->fp(), deopt_pc); | 1982 frame->fp(), deopt_pc); |
1959 } | 1983 } |
1960 } | 1984 } |
| 1985 #endif // !DBC |
1961 | 1986 |
1962 // Mark code as dead (do not GC its embedded objects). | 1987 // Mark code as dead (do not GC its embedded objects). |
1963 optimized_code.set_is_alive(false); | 1988 optimized_code.set_is_alive(false); |
1964 } | 1989 } |
1965 | 1990 |
1966 | 1991 |
1967 // Currently checks only that all optimized frames have kDeoptIndex | 1992 // Currently checks only that all optimized frames have kDeoptIndex |
1968 // and unoptimized code has the kDeoptAfter. | 1993 // and unoptimized code has the kDeoptAfter. |
1969 void DeoptimizeFunctionsOnStack() { | 1994 void DeoptimizeFunctionsOnStack() { |
1970 DartFrameIterator iterator; | 1995 DartFrameIterator iterator; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2048 Function::Handle(thread->zone(), optimized_code.function()); | 2073 Function::Handle(thread->zone(), optimized_code.function()); |
2049 const bool deoptimizing_code = top_function.HasOptimizedCode(); | 2074 const bool deoptimizing_code = top_function.HasOptimizedCode(); |
2050 if (FLAG_trace_deoptimization) { | 2075 if (FLAG_trace_deoptimization) { |
2051 const Function& function = Function::Handle(optimized_code.function()); | 2076 const Function& function = Function::Handle(optimized_code.function()); |
2052 THR_Print("== Deoptimizing code for '%s', %s, %s\n", | 2077 THR_Print("== Deoptimizing code for '%s', %s, %s\n", |
2053 function.ToFullyQualifiedCString(), | 2078 function.ToFullyQualifiedCString(), |
2054 deoptimizing_code ? "code & frame" : "frame", | 2079 deoptimizing_code ? "code & frame" : "frame", |
2055 is_lazy_deopt ? "lazy-deopt" : ""); | 2080 is_lazy_deopt ? "lazy-deopt" : ""); |
2056 } | 2081 } |
2057 | 2082 |
| 2083 #if !defined(TARGET_ARCH_DBC) |
2058 if (is_lazy_deopt) { | 2084 if (is_lazy_deopt) { |
2059 uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp()); | 2085 uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp()); |
2060 if (FLAG_trace_deoptimization) { | 2086 if (FLAG_trace_deoptimization) { |
2061 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), | 2087 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), |
2062 deopt_pc); | 2088 deopt_pc); |
2063 } | 2089 } |
2064 | 2090 |
2065 // N.B.: Update frame before updating pending deopt table. The profiler | 2091 // N.B.: Update frame before updating pending deopt table. The profiler |
2066 // may attempt a stack walk in between. | 2092 // may attempt a stack walk in between. |
2067 caller_frame->set_pc(deopt_pc); | 2093 caller_frame->set_pc(deopt_pc); |
2068 ASSERT(!caller_frame->IsMarkedForLazyDeopt()); | |
2069 ASSERT(caller_frame->pc() == deopt_pc); | 2094 ASSERT(caller_frame->pc() == deopt_pc); |
2070 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc())); | 2095 ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc())); |
2071 isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp()); | 2096 isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp()); |
2072 } else { | 2097 } else { |
2073 if (FLAG_trace_deoptimization) { | 2098 if (FLAG_trace_deoptimization) { |
2074 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), | 2099 THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n", caller_frame->fp(), |
2075 caller_frame->pc()); | 2100 caller_frame->pc()); |
2076 } | 2101 } |
2077 } | 2102 } |
| 2103 #endif // !DBC |
2078 | 2104 |
2079 // Copy the saved registers from the stack. | 2105 // Copy the saved registers from the stack. |
2080 fpu_register_t* fpu_registers; | 2106 fpu_register_t* fpu_registers; |
2081 intptr_t* cpu_registers; | 2107 intptr_t* cpu_registers; |
2082 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers); | 2108 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers); |
2083 | 2109 |
2084 // Create the DeoptContext. | 2110 // Create the DeoptContext. |
2085 DeoptContext* deopt_context = new DeoptContext( | 2111 DeoptContext* deopt_context = new DeoptContext( |
2086 caller_frame, optimized_code, DeoptContext::kDestIsOriginalFrame, | 2112 caller_frame, optimized_code, DeoptContext::kDestIsOriginalFrame, |
2087 fpu_registers, cpu_registers, is_lazy_deopt != 0, deoptimizing_code); | 2113 fpu_registers, cpu_registers, is_lazy_deopt != 0, deoptimizing_code); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
2236 const TypedData& new_data = | 2262 const TypedData& new_data = |
2237 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
2238 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
2239 typed_data_cell.SetAt(0, new_data); | 2265 typed_data_cell.SetAt(0, new_data); |
2240 arguments.SetReturn(new_data); | 2266 arguments.SetReturn(new_data); |
2241 } | 2267 } |
2242 | 2268 |
2243 | 2269 |
2244 } // namespace dart | 2270 } // namespace dart |
OLD | NEW |