Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
| 10 | 10 |
| 11 #if !defined(USING_SIMULATOR) | 11 #if !defined(USING_SIMULATOR) |
| 12 #error "DBC is a simulated architecture" | 12 #error "DBC is a simulated architecture" |
| 13 #endif | 13 #endif |
| 14 | 14 |
| 15 #include "vm/simulator.h" | 15 #include "vm/simulator.h" |
| 16 | 16 |
| 17 #include "vm/assembler.h" | 17 #include "vm/assembler.h" |
| 18 #include "vm/compiler.h" | 18 #include "vm/compiler.h" |
| 19 #include "vm/constants_dbc.h" | 19 #include "vm/constants_dbc.h" |
| 20 #include "vm/cpu.h" | 20 #include "vm/cpu.h" |
| 21 #include "vm/dart_entry.h" | 21 #include "vm/dart_entry.h" |
| 22 #include "vm/debugger.h" | 22 #include "vm/debugger.h" |
| 23 #include "vm/disassembler.h" | 23 #include "vm/disassembler.h" |
| 24 #include "vm/flow_graph_compiler.h" | |
| 24 #include "vm/lockers.h" | 25 #include "vm/lockers.h" |
| 25 #include "vm/native_arguments.h" | 26 #include "vm/native_arguments.h" |
| 26 #include "vm/native_entry.h" | 27 #include "vm/native_entry.h" |
| 27 #include "vm/object.h" | 28 #include "vm/object.h" |
| 28 #include "vm/object_store.h" | 29 #include "vm/object_store.h" |
| 29 #include "vm/os_thread.h" | 30 #include "vm/os_thread.h" |
| 30 #include "vm/stack_frame.h" | 31 #include "vm/stack_frame.h" |
| 31 | 32 |
| 32 namespace dart { | 33 namespace dart { |
| 33 | 34 |
| (...skipping 1937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1971 const RawSmi* actual_cid = | 1972 const RawSmi* actual_cid = |
| 1972 SimulatorHelpers::GetClassIdAsSmi(static_cast<RawObject*>(FP[rA])); | 1973 SimulatorHelpers::GetClassIdAsSmi(static_cast<RawObject*>(FP[rA])); |
| 1973 const RawSmi* desired_cid = RAW_CAST(Smi, LOAD_CONSTANT(rD)); | 1974 const RawSmi* desired_cid = RAW_CAST(Smi, LOAD_CONSTANT(rD)); |
| 1974 if (actual_cid == desired_cid) { | 1975 if (actual_cid == desired_cid) { |
| 1975 pc++; | 1976 pc++; |
| 1976 } | 1977 } |
| 1977 DISPATCH(); | 1978 DISPATCH(); |
| 1978 } | 1979 } |
| 1979 | 1980 |
| 1980 { | 1981 { |
| 1982 BYTECODE(CheckNull, A_D); | |
| 1983 RawObject* obj = FP[rA]; | |
| 1984 if (((rD == 1) && (obj != null_value)) || | |
| 1985 ((rD == 0) && (obj == null_value))) { | |
| 1986 pc++; | |
| 1987 } | |
| 1988 DISPATCH(); | |
| 1989 } | |
| 1990 | |
| 1991 { | |
| 1992 BYTECODE(CheckDenseSwitchTOS, A_D); | |
| 1993 const intptr_t cid_mask = Smi::Value(RAW_CAST(Smi, *SP--)); | |
| 1994 const intptr_t cid_min = Smi::Value(RAW_CAST(Smi, *SP--)); | |
| 1995 const ICData& ic_data = | |
| 1996 ICData::Handle(RAW_CAST(ICData, LOAD_CONSTANT(rD))); | |
| 1997 const intptr_t value = reinterpret_cast<intptr_t>(FP[rA]); | |
| 1998 const bool is_smi = ((value & kSmiTagMask) == kSmiTag); | |
| 1999 if (is_smi) { | |
| 2000 //OS::PrintErr("CheckDenseSwitchTOS: Smi\n"); | |
| 2001 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { | |
| 2002 //OS::PrintErr("\tCheckDenseSwitchTOS: receiver is smi\n"); | |
| 2003 pc++; | |
| 2004 } else { | |
| 2005 //OS::PrintErr("\tCheckDenseSwitchTOS: receiver is NOT smi\n"); | |
| 2006 } | |
| 2007 } else { | |
| 2008 const intptr_t cid_max = Utils::HighestBit(cid_mask) + cid_min; | |
| 2009 const intptr_t cid = SimulatorHelpers::GetClassId(FP[rA]); | |
| 2010 //OS::PrintErr("\tCheckDenseSwitchTOS: cid_min = %ld, cid_max = %ld, cid = %ld\n", | |
| 2011 //cid_min, cid_max, cid); | |
| 2012 // The cid is in-bounds, and the bit is set in the mask. | |
| 2013 if ((cid >= cid_min) && (cid <= cid_max) && | |
| 2014 ((cid_mask & (1 << (cid - cid_min))) != 0)) { | |
| 2015 //OS::PrintErr("\tCheckDenseSwitchTOS: Good\n"); | |
| 2016 pc++; | |
| 2017 } else { | |
| 2018 //OS::PrintErr("\tCheckDenseSwitchTOS: Not Good\n"); | |
| 2019 } | |
| 2020 } | |
| 2021 DISPATCH(); | |
| 2022 } | |
| 2023 | |
| 2024 { | |
| 2025 BYTECODE(CheckForCid, A_D); | |
| 2026 const ICData& ic_data = | |
| 2027 ICData::Handle(RAW_CAST(ICData, LOAD_CONSTANT(rD))); | |
| 2028 const intptr_t value = reinterpret_cast<intptr_t>(FP[rA]); | |
| 2029 const bool is_smi = ((value & kSmiTagMask) == kSmiTag); | |
| 2030 if (is_smi) { | |
| 2031 //OS::PrintErr("CheckForCid: Smi\n"); | |
| 2032 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { | |
| 2033 //OS::PrintErr("\tCheckForCid: receiver is smi\n"); | |
| 2034 pc++; | |
| 2035 } else { | |
| 2036 //OS::PrintErr("\tCheckForCid: receiver is not smi\n"); | |
| 2037 } | |
| 2038 } else { | |
| 2039 const intptr_t cid = SimulatorHelpers::GetClassId(FP[rA]); | |
| 2040 GrowableArray<CidTarget> sorted_ic_data; | |
| 2041 FlowGraphCompiler::SortICDataByCount(ic_data, | |
| 2042 &sorted_ic_data, | |
| 2043 /* drop_smi = */ true); | |
| 2044 const intptr_t num_checks = sorted_ic_data.length(); | |
| 2045 //OS::PrintErr("CheckForCid: cid = %ld, num_checks = %ld\n", | |
| 2046 //cid, num_checks); | |
| 2047 for (intptr_t i = 0; i < num_checks; i++) { | |
| 2048 const intptr_t data_cid = sorted_ic_data[i].cid; | |
| 2049 //OS::PrintErr("\tCheckForCid: looking at %ld\n", data_cid); | |
| 2050 ASSERT(cid != kSmiCid); | |
| 2051 if (cid == data_cid) { | |
| 2052 //OS::PrintErr("\tCheckForCid: Found\n"); | |
| 2053 pc++; | |
| 2054 break; | |
| 2055 } | |
| 2056 } | |
| 2057 } | |
| 2058 DISPATCH(); | |
| 2059 } | |
| 2060 | |
| 2061 { | |
| 1981 BYTECODE(IfEqStrictTOS, 0); | 2062 BYTECODE(IfEqStrictTOS, 0); |
| 1982 SP -= 2; | 2063 SP -= 2; |
| 1983 if (SP[1] != SP[2]) { | 2064 if (SP[1] != SP[2]) { |
| 1984 pc++; | 2065 pc++; |
| 1985 } | 2066 } |
| 1986 DISPATCH(); | 2067 DISPATCH(); |
| 1987 } | 2068 } |
| 1988 | 2069 |
| 1989 { | 2070 { |
| 1990 BYTECODE(IfNeStrictTOS, 0); | 2071 BYTECODE(IfNeStrictTOS, 0); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2109 ASSERT(!index->IsHeapObject()); | 2190 ASSERT(!index->IsHeapObject()); |
| 2110 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); | 2191 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); |
| 2111 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); | 2192 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); |
| 2112 DISPATCH(); | 2193 DISPATCH(); |
| 2113 } | 2194 } |
| 2114 | 2195 |
| 2115 { | 2196 { |
| 2116 BYTECODE(Deopt, A_D); | 2197 BYTECODE(Deopt, A_D); |
| 2117 const bool is_lazy = rD == 0; | 2198 const bool is_lazy = rD == 0; |
| 2118 | 2199 |
| 2200 //OS::PrintErr("Deopt instr pc = %p\n", pc - 1); | |
| 2201 | |
| 2119 // Preserve result of the previous call. | 2202 // Preserve result of the previous call. |
| 2120 // TODO(vegorov) we could have actually included result into the | 2203 // TODO(vegorov) we could have actually included result into the |
| 2121 // deoptimization environment because it is passed through the stack. | 2204 // deoptimization environment because it is passed through the stack. |
| 2122 // If we do then we could remove special result handling from this code. | 2205 // If we do then we could remove special result handling from this code. |
| 2123 RawObject* result = SP[0]; | 2206 RawObject* result = SP[0]; |
| 2124 | 2207 |
| 2125 // When not preserving the result, we still need to preserve SP[0] as it | 2208 // When not preserving the result, we still need to preserve SP[0] as it |
| 2126 // contains some temporary expression. | 2209 // contains some temporary expression. |
| 2127 if (!is_lazy) { | 2210 if (!is_lazy) { |
| 2128 SP++; | 2211 SP++; |
| 2129 } | 2212 } |
| 2130 | 2213 |
| 2131 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. | 2214 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
| 2132 // The code in this frame may not cause GC. | 2215 // The code in this frame may not cause GC. |
| 2133 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. | 2216 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. |
| 2134 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); | 2217 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); |
| 2135 const intptr_t frame_size_in_bytes = | 2218 const intptr_t frame_size_in_bytes = |
| 2136 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0); | 2219 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0); |
| 2137 LeaveSyntheticFrame(&FP, &SP); | 2220 LeaveSyntheticFrame(&FP, &SP); |
| 2138 | 2221 |
| 2139 SP = FP + (frame_size_in_bytes / kWordSize); | 2222 SP = FP + (frame_size_in_bytes / kWordSize); |
| 2140 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); | 2223 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); |
| 2141 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP)); | 2224 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP)); |
| 2142 | 2225 |
| 2143 // We are now inside a valid frame. | 2226 // We are now inside a valid frame. |
| 2144 { | 2227 { |
| 2145 if (is_lazy) { | 2228 if (is_lazy) { |
| 2146 *++SP = result; // Preserve result (call below can cause GC). | 2229 *++SP = result; // Preserve result (call below can cause GC). |
| 2147 } | 2230 } |
| 2148 *++SP = 0; // Space for the result: number of materialization args. | 2231 *++SP = 0; // Space for the result: number of materialization args. |
|
Vyacheslav Egorov (Google)
2016/06/24 14:47:07
the call actually returns number of materializatio
zra
2016/06/24 22:37:49
Acknowledged.
| |
| 2149 Exit(thread, FP, SP + 1, /*pc=*/0); | 2232 Exit(thread, FP, SP + 1, /*pc=*/0); |
| 2150 NativeArguments native_args(thread, 0, SP, SP); | 2233 NativeArguments native_args(thread, 0, SP, SP); |
| 2151 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args); | 2234 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args); |
| 2152 } | 2235 } |
| 2153 const intptr_t materialization_arg_count = | 2236 const intptr_t materialization_arg_count = |
| 2154 Smi::Value(RAW_CAST(Smi, *SP--)); | 2237 Smi::Value(RAW_CAST(Smi, *SP--)); |
|
Vyacheslav Egorov (Google)
2016/06/24 14:47:07
this needs to be divided by kWordSize.
sorry abou
zra
2016/06/24 22:37:49
Done.
| |
| 2155 if (is_lazy) { | 2238 if (is_lazy) { |
| 2156 // Reload the result. It might have been relocated by GC. | 2239 // Reload the result. It might have been relocated by GC. |
| 2157 result = *SP--; | 2240 result = *SP--; |
| 2158 } | 2241 } |
| 2159 | 2242 |
| 2160 // Restore caller PC. | 2243 // Restore caller PC. |
| 2161 pc = SavedCallerPC(FP); | 2244 pc = SavedCallerPC(FP); |
| 2162 | 2245 |
| 2163 // Check if it is a fake PC marking the entry frame. | 2246 // Check if it is a fake PC marking the entry frame. |
| 2164 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); | 2247 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2290 special_[kExceptionSpecialIndex] = raw_exception; | 2373 special_[kExceptionSpecialIndex] = raw_exception; |
| 2291 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 2374 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
| 2292 buf->Longjmp(); | 2375 buf->Longjmp(); |
| 2293 UNREACHABLE(); | 2376 UNREACHABLE(); |
| 2294 } | 2377 } |
| 2295 | 2378 |
| 2296 } // namespace dart | 2379 } // namespace dart |
| 2297 | 2380 |
| 2298 | 2381 |
| 2299 #endif // defined TARGET_ARCH_DBC | 2382 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |