OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/assembler-inl.h" | 10 #include "src/assembler-inl.h" |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 break; | 820 break; |
821 case TranslatedFrame::kGetter: | 821 case TranslatedFrame::kGetter: |
822 DoComputeAccessorStubFrame(translated_frame, frame_index, false); | 822 DoComputeAccessorStubFrame(translated_frame, frame_index, false); |
823 break; | 823 break; |
824 case TranslatedFrame::kSetter: | 824 case TranslatedFrame::kSetter: |
825 DoComputeAccessorStubFrame(translated_frame, frame_index, true); | 825 DoComputeAccessorStubFrame(translated_frame, frame_index, true); |
826 break; | 826 break; |
827 case TranslatedFrame::kCompiledStub: | 827 case TranslatedFrame::kCompiledStub: |
828 DoComputeCompiledStubFrame(translated_frame, frame_index); | 828 DoComputeCompiledStubFrame(translated_frame, frame_index); |
829 break; | 829 break; |
| 830 case TranslatedFrame::kBuiltinContinuation: |
| 831 DoComputeBuiltinContinuation(translated_frame, frame_index, false); |
| 832 break; |
| 833 case TranslatedFrame::kJavaScriptBuiltinContinuation: |
| 834 DoComputeBuiltinContinuation(translated_frame, frame_index, true); |
| 835 break; |
830 case TranslatedFrame::kInvalid: | 836 case TranslatedFrame::kInvalid: |
831 FATAL("invalid frame"); | 837 FATAL("invalid frame"); |
832 break; | 838 break; |
833 } | 839 } |
834 } | 840 } |
835 | 841 |
836 // Print some helpful diagnostic information. | 842 // Print some helpful diagnostic information. |
837 if (trace_scope_ != NULL) { | 843 if (trace_scope_ != NULL) { |
838 double ms = timer.Elapsed().InMillisecondsF(); | 844 double ms = timer.Elapsed().InMillisecondsF(); |
839 int index = output_count_ - 1; // Index of the topmost frame. | 845 int index = output_count_ - 1; // Index of the topmost frame. |
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2154 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | 2160 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
2155 } | 2161 } |
2156 output_frame->SetState( | 2162 output_frame->SetState( |
2157 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); | 2163 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); |
2158 Code* notify_failure = | 2164 Code* notify_failure = |
2159 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); | 2165 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); |
2160 output_frame->SetContinuation( | 2166 output_frame->SetContinuation( |
2161 reinterpret_cast<intptr_t>(notify_failure->entry())); | 2167 reinterpret_cast<intptr_t>(notify_failure->entry())); |
2162 } | 2168 } |
2163 | 2169 |
| 2170 // BuiltinContinuationFrames capture the machine state that is expected as input |
| 2171 // to a builtin, including both input register values and stack parameters. When |
| 2172 // the frame is reactivated (i.e. the frame below it returns), a |
| 2173 // ContinueToBuiltin stub restores the register state from the frame and tail |
| 2174 // calls to the actual target builtin, making it appear that the stub had been |
| 2175 // directly called by the frame above it. The input values to populate the frame |
| 2176 // are taken from the deopt's FrameState. |
| 2177 // |
| 2178 // Frame translation happens in two modes, EAGER and LAZY. In EAGER mode, all of |
| 2179 // the parameters to the Builtin are explicitly specified in the TurboFan |
| 2180 // FrameState node. In LAZY mode, there is always one fewer parameters specified |
| 2181 // in the FrameState than expected by the Builtin. In that case, construction of |
| 2182 // BuiltinContinuationFrame adds the final missing parameter during |
| 2183 // deoptimization, and that parameter is always on the stack and contains the |
| 2184 // value returned from the callee of the call site triggering the LAZY deopt |
| 2185 // (e.g. rax on x64). This requires that continuation Builtins for LAZY deopts |
| 2186 // must have at least one stack parameter. |
| 2187 // |
| 2188 // TO |
| 2189 // | .... | |
| 2190 // +-------------------------+ |
| 2191 // | builtin param 0 |<- FrameState input value n becomes |
| 2192 // +-------------------------+ |
| 2193 // | ... | |
| 2194 // +-------------------------+ |
| 2195 // | builtin param m |<- FrameState input value n+m-1, or in |
| 2196 // +-------------------------+ the LAZY case, return LAZY result value |
| 2197 // | ContinueToBuiltin entry | |
| 2198 // +-------------------------+ |
| 2199 // | | saved frame (FP) | |
| 2200 // | +=========================+<- fpreg |
| 2201 // | |constant pool (if ool_cp)| |
| 2202 // v +-------------------------+ |
| 2203 // |BUILTIN_CONTINUATION mark| |
| 2204 // +-------------------------+ |
| 2205 // | JS Builtin code object | |
| 2206 // +-------------------------+ |
| 2207 // | builtin input GPR reg0 |<- populated from deopt FrameState using |
| 2208 // +-------------------------+ the builtin's CallInterfaceDescriptor |
| 2209 // | ... | to map a FrameState's 0..n-1 inputs to |
| 2210 // +-------------------------+ the builtin's n input register params. |
| 2211 // | builtin input GPR regn | |
| 2212 // |-------------------------|<- spreg |
| 2213 // |
| 2214 void Deoptimizer::DoComputeBuiltinContinuation( |
| 2215 TranslatedFrame* translated_frame, int frame_index, |
| 2216 bool java_script_builtin) { |
| 2217 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 2218 int input_index = 0; |
| 2219 |
| 2220 // The output frame must have room for all of the parameters that need to be |
| 2221 // passed to the builtin continuation. |
| 2222 int height_in_words = translated_frame->height(); |
| 2223 |
| 2224 BailoutId bailout_id = translated_frame->node_id(); |
| 2225 Builtins::Name builtin_name = Builtins::GetBuiltinFromBailoutId(bailout_id); |
| 2226 Code* builtin = isolate()->builtins()->builtin(builtin_name); |
| 2227 Callable continuation_callable = |
| 2228 Builtins::CallableFor(isolate(), builtin_name); |
| 2229 CallInterfaceDescriptor continuation_descriptor = |
| 2230 continuation_callable.descriptor(); |
| 2231 |
| 2232 bool is_bottommost = (0 == frame_index); |
| 2233 bool is_topmost = (output_count_ - 1 == frame_index); |
| 2234 bool must_handle_result = !is_topmost || bailout_type_ == LAZY; |
| 2235 |
| 2236 const RegisterConfiguration* config(RegisterConfiguration::Turbofan()); |
| 2237 int allocatable_register_count = config->num_allocatable_general_registers(); |
| 2238 int register_parameter_count = |
| 2239 continuation_descriptor.GetRegisterParameterCount(); |
| 2240 // Make sure to account for the context by removing it from the register |
| 2241 // parameter count. |
| 2242 int stack_param_count = height_in_words - register_parameter_count - 1; |
| 2243 if (must_handle_result) stack_param_count++; |
| 2244 int output_frame_size = |
| 2245 kPointerSize * (stack_param_count + allocatable_register_count) + |
| 2246 TYPED_FRAME_SIZE(2); // For destination builtin code and registers |
| 2247 |
| 2248 // Validate types of parameters. They must all be tagged except for argc for |
| 2249 // JS builtins. |
| 2250 bool has_argc = false; |
| 2251 for (int i = 0; i < register_parameter_count; ++i) { |
| 2252 MachineType type = continuation_descriptor.GetParameterType(i); |
| 2253 int code = continuation_descriptor.GetRegisterParameter(i).code(); |
| 2254 // Only tagged and int32 arguments are supported, and int32 only for the |
| 2255 // arguments count on JavaScript builtins. |
| 2256 if (type == MachineType::Int32()) { |
| 2257 CHECK_EQ(code, kJavaScriptCallArgCountRegister.code()); |
| 2258 has_argc = true; |
| 2259 } else { |
| 2260 // Any other argument must be a tagged value. |
| 2261 CHECK(IsAnyTagged(type.representation())); |
| 2262 } |
| 2263 } |
| 2264 CHECK_EQ(java_script_builtin, has_argc); |
| 2265 |
| 2266 if (trace_scope_ != NULL) { |
| 2267 PrintF(trace_scope_->file(), |
| 2268 " translating BuiltinContinuation to %s, stack param count %d\n", |
| 2269 Builtins::name(builtin_name), stack_param_count); |
| 2270 } |
| 2271 |
| 2272 unsigned output_frame_offset = output_frame_size; |
| 2273 FrameDescription* output_frame = |
| 2274 new (output_frame_size) FrameDescription(output_frame_size); |
| 2275 output_[frame_index] = output_frame; |
| 2276 |
| 2277 // The top address of the frame is computed from the previous frame's top and |
| 2278 // this frame's size. |
| 2279 intptr_t top_address; |
| 2280 if (is_bottommost) { |
| 2281 top_address = caller_frame_top_ - output_frame_size; |
| 2282 } else { |
| 2283 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 2284 } |
| 2285 output_frame->SetTop(top_address); |
| 2286 |
| 2287 output_frame->SetState( |
| 2288 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); |
| 2289 |
| 2290 // Get the possible JSFunction for the case that |
| 2291 intptr_t maybe_function = |
| 2292 reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2293 ++value_iterator; |
| 2294 |
| 2295 std::vector<intptr_t> register_values; |
| 2296 int total_registers = config->num_general_registers(); |
| 2297 register_values.resize(total_registers, 0); |
| 2298 for (int i = 0; i < total_registers; ++i) { |
| 2299 register_values[i] = 0; |
| 2300 } |
| 2301 |
| 2302 intptr_t value; |
| 2303 |
| 2304 Register result_reg = FullCodeGenerator::result_register(); |
| 2305 if (must_handle_result) { |
| 2306 value = input_->GetRegister(result_reg.code()); |
| 2307 } else { |
| 2308 value = reinterpret_cast<intptr_t>(isolate()->heap()->undefined_value()); |
| 2309 } |
| 2310 output_frame->SetRegister(result_reg.code(), value); |
| 2311 |
| 2312 int translated_stack_parameters = |
| 2313 must_handle_result ? stack_param_count - 1 : stack_param_count; |
| 2314 |
| 2315 for (int i = 0; i < translated_stack_parameters; ++i) { |
| 2316 output_frame_offset -= kPointerSize; |
| 2317 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 2318 output_frame_offset); |
| 2319 } |
| 2320 |
| 2321 if (must_handle_result) { |
| 2322 output_frame_offset -= kPointerSize; |
| 2323 WriteValueToOutput(isolate()->heap()->the_hole_value(), input_index, |
| 2324 frame_index, output_frame_offset, |
| 2325 "placeholder for return result on lazy deopt "); |
| 2326 } |
| 2327 |
| 2328 for (int i = 0; i < register_parameter_count; ++i) { |
| 2329 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2330 int code = continuation_descriptor.GetRegisterParameter(i).code(); |
| 2331 register_values[code] = value; |
| 2332 ++input_index; |
| 2333 ++value_iterator; |
| 2334 } |
| 2335 |
| 2336 // The context register is always implicit in the CallInterfaceDescriptor but |
| 2337 // its register must be explicitly set when continuing to the builtin. Make |
| 2338 // sure that it's harvested from the translation and copied into the register |
| 2339 // set (it was automatically added at the end of the FrameState by the |
| 2340 // instruction selector). |
| 2341 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2342 register_values[kContextRegister.code()] = value; |
| 2343 output_frame->SetContext(value); |
| 2344 output_frame->SetRegister(kContextRegister.code(), value); |
| 2345 ++input_index; |
| 2346 ++value_iterator; |
| 2347 |
| 2348 // Set caller's PC (JSFunction continuation). |
| 2349 output_frame_offset -= kPCOnStackSize; |
| 2350 if (is_bottommost) { |
| 2351 value = caller_pc_; |
| 2352 } else { |
| 2353 value = output_[frame_index - 1]->GetPc(); |
| 2354 } |
| 2355 output_frame->SetCallerPc(output_frame_offset, value); |
| 2356 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2357 "caller's pc\n"); |
| 2358 |
| 2359 // Read caller's FP from the previous frame, and set this frame's FP. |
| 2360 output_frame_offset -= kFPOnStackSize; |
| 2361 if (is_bottommost) { |
| 2362 value = caller_fp_; |
| 2363 } else { |
| 2364 value = output_[frame_index - 1]->GetFp(); |
| 2365 } |
| 2366 output_frame->SetCallerFp(output_frame_offset, value); |
| 2367 intptr_t fp_value = top_address + output_frame_offset; |
| 2368 output_frame->SetFp(fp_value); |
| 2369 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2370 "caller's fp\n"); |
| 2371 |
| 2372 if (FLAG_enable_embedded_constant_pool) { |
| 2373 // Read the caller's constant pool from the previous frame. |
| 2374 output_frame_offset -= kPointerSize; |
| 2375 if (is_bottommost) { |
| 2376 value = caller_constant_pool_; |
| 2377 } else { |
| 2378 value = output_[frame_index - 1]->GetConstantPool(); |
| 2379 } |
| 2380 output_frame->SetCallerConstantPool(output_frame_offset, value); |
| 2381 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2382 "caller's constant_pool\n"); |
| 2383 } |
| 2384 |
| 2385 // A marker value is used in place of the context. |
| 2386 output_frame_offset -= kPointerSize; |
| 2387 intptr_t marker = |
| 2388 java_script_builtin |
| 2389 ? StackFrame::TypeToMarker( |
| 2390 StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION) |
| 2391 : StackFrame::TypeToMarker(StackFrame::BUILTIN_CONTINUATION); |
| 2392 output_frame->SetFrameSlot(output_frame_offset, marker); |
| 2393 DebugPrintOutputSlot(marker, frame_index, output_frame_offset, |
| 2394 "context (builtin continuation sentinel)\n"); |
| 2395 |
| 2396 output_frame_offset -= kPointerSize; |
| 2397 value = java_script_builtin ? maybe_function : 0; |
| 2398 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2399 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2400 java_script_builtin ? "JSFunction\n" : "unused\n"); |
| 2401 |
| 2402 // The builtin to continue to |
| 2403 output_frame_offset -= kPointerSize; |
| 2404 value = reinterpret_cast<intptr_t>(builtin); |
| 2405 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2406 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2407 "builtin address\n"); |
| 2408 |
| 2409 for (int i = 0; i < allocatable_register_count; ++i) { |
| 2410 output_frame_offset -= kPointerSize; |
| 2411 int code = config->GetAllocatableGeneralCode(i); |
| 2412 value = register_values[code]; |
| 2413 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2414 if (trace_scope_ != nullptr) { |
| 2415 ScopedVector<char> str(128); |
| 2416 if (java_script_builtin && |
| 2417 code == kJavaScriptCallArgCountRegister.code()) { |
| 2418 SNPrintF( |
| 2419 str, |
| 2420 "tagged argument count %s (will be untagged by continuation)\n", |
| 2421 config->GetGeneralRegisterName(code)); |
| 2422 } else { |
| 2423 SNPrintF(str, "builtin register argument %s\n", |
| 2424 config->GetGeneralRegisterName(code)); |
| 2425 } |
| 2426 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2427 str.start()); |
| 2428 } |
| 2429 } |
| 2430 |
| 2431 // Ensure the frame pointer register points to the callee's frame. The builtin |
| 2432 // will build its own frame once we continue to it. |
| 2433 Register fp_reg = JavaScriptFrame::fp_register(); |
| 2434 output_frame->SetRegister(fp_reg.code(), output_[frame_index - 1]->GetFp()); |
| 2435 |
| 2436 Code* continue_to_builtin = |
| 2437 java_script_builtin |
| 2438 ? (must_handle_result |
| 2439 ? isolate()->builtins()->builtin( |
| 2440 Builtins::kContinueToJavaScriptBuiltinWithResult) |
| 2441 : isolate()->builtins()->builtin( |
| 2442 Builtins::kContinueToJavaScriptBuiltin)) |
| 2443 : (must_handle_result |
| 2444 ? isolate()->builtins()->builtin( |
| 2445 Builtins::kContinueToCodeStubBuiltinWithResult) |
| 2446 : isolate()->builtins()->builtin( |
| 2447 Builtins::kContinueToCodeStubBuiltin)); |
| 2448 output_frame->SetPc( |
| 2449 reinterpret_cast<intptr_t>(continue_to_builtin->instruction_start())); |
| 2450 |
| 2451 Code* continuation = |
| 2452 isolate()->builtins()->builtin(Builtins::kNotifyBuiltinContinuation); |
| 2453 output_frame->SetContinuation( |
| 2454 reinterpret_cast<intptr_t>(continuation->entry())); |
| 2455 } |
2164 | 2456 |
2165 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 2457 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
2166 // Walk to the last JavaScript output frame to find out if it has | 2458 // Walk to the last JavaScript output frame to find out if it has |
2167 // adapted arguments. | 2459 // adapted arguments. |
2168 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 2460 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
2169 if (frame_index != 0) it->Advance(); | 2461 if (frame_index != 0) it->Advance(); |
2170 } | 2462 } |
2171 translated_state_.Prepare(it->frame()->has_adapted_arguments(), | 2463 translated_state_.Prepare(it->frame()->has_adapted_arguments(), |
2172 reinterpret_cast<Address>(stack_fp_)); | 2464 reinterpret_cast<Address>(stack_fp_)); |
2173 | 2465 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2398 return is_negative ? -result : result; | 2690 return is_negative ? -result : result; |
2399 } | 2691 } |
2400 | 2692 |
2401 | 2693 |
2402 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { | 2694 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { |
2403 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); | 2695 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); |
2404 contents_.CopyTo(result->GetDataStartAddress()); | 2696 contents_.CopyTo(result->GetDataStartAddress()); |
2405 return result; | 2697 return result; |
2406 } | 2698 } |
2407 | 2699 |
| 2700 void Translation::BeginBuiltinContinuationFrame(BailoutId bailout_id, |
| 2701 int literal_id, |
| 2702 unsigned height) { |
| 2703 buffer_->Add(BUILTIN_CONTINUATION_FRAME); |
| 2704 buffer_->Add(bailout_id.ToInt()); |
| 2705 buffer_->Add(literal_id); |
| 2706 buffer_->Add(height); |
| 2707 } |
| 2708 |
| 2709 void Translation::BeginJavaScriptBuiltinContinuationFrame(BailoutId bailout_id, |
| 2710 int literal_id, |
| 2711 unsigned height) { |
| 2712 buffer_->Add(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME); |
| 2713 buffer_->Add(bailout_id.ToInt()); |
| 2714 buffer_->Add(literal_id); |
| 2715 buffer_->Add(height); |
| 2716 } |
| 2717 |
2408 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, | 2718 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, |
2409 unsigned height) { | 2719 unsigned height) { |
2410 buffer_->Add(CONSTRUCT_STUB_FRAME); | 2720 buffer_->Add(CONSTRUCT_STUB_FRAME); |
2411 buffer_->Add(bailout_id.ToInt()); | 2721 buffer_->Add(bailout_id.ToInt()); |
2412 buffer_->Add(literal_id); | 2722 buffer_->Add(literal_id); |
2413 buffer_->Add(height); | 2723 buffer_->Add(height); |
2414 } | 2724 } |
2415 | 2725 |
2416 | 2726 |
2417 void Translation::BeginGetterStubFrame(int literal_id) { | 2727 void Translation::BeginGetterStubFrame(int literal_id) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2600 case LITERAL: | 2910 case LITERAL: |
2601 case COMPILED_STUB_FRAME: | 2911 case COMPILED_STUB_FRAME: |
2602 case TAIL_CALLER_FRAME: | 2912 case TAIL_CALLER_FRAME: |
2603 return 1; | 2913 return 1; |
2604 case BEGIN: | 2914 case BEGIN: |
2605 case ARGUMENTS_ADAPTOR_FRAME: | 2915 case ARGUMENTS_ADAPTOR_FRAME: |
2606 return 2; | 2916 return 2; |
2607 case JS_FRAME: | 2917 case JS_FRAME: |
2608 case INTERPRETED_FRAME: | 2918 case INTERPRETED_FRAME: |
2609 case CONSTRUCT_STUB_FRAME: | 2919 case CONSTRUCT_STUB_FRAME: |
| 2920 case BUILTIN_CONTINUATION_FRAME: |
| 2921 case JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: |
2610 return 3; | 2922 return 3; |
2611 case ARGUMENTS_ELEMENTS: | 2923 case ARGUMENTS_ELEMENTS: |
2612 case ARGUMENTS_LENGTH: | 2924 case ARGUMENTS_LENGTH: |
2613 return 1; | 2925 return 1; |
2614 } | 2926 } |
2615 FATAL("Unexpected translation type"); | 2927 FATAL("Unexpected translation type"); |
2616 return -1; | 2928 return -1; |
2617 } | 2929 } |
2618 | 2930 |
2619 | 2931 |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3206 } | 3518 } |
3207 | 3519 |
3208 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 3520 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
3209 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { | 3521 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
3210 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, | 3522 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, |
3211 height); | 3523 height); |
3212 frame.node_id_ = bailout_id; | 3524 frame.node_id_ = bailout_id; |
3213 return frame; | 3525 return frame; |
3214 } | 3526 } |
3215 | 3527 |
| 3528 TranslatedFrame TranslatedFrame::BuiltinContinuationFrame( |
| 3529 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
| 3530 base::OS::DebugBreak(); |
| 3531 TranslatedFrame frame(kBuiltinContinuation, shared_info->GetIsolate(), |
| 3532 shared_info, height); |
| 3533 frame.node_id_ = bailout_id; |
| 3534 return frame; |
| 3535 } |
| 3536 |
| 3537 TranslatedFrame TranslatedFrame::JavaScriptBuiltinContinuationFrame( |
| 3538 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
| 3539 TranslatedFrame frame(kJavaScriptBuiltinContinuation, |
| 3540 shared_info->GetIsolate(), shared_info, height); |
| 3541 frame.node_id_ = bailout_id; |
| 3542 return frame; |
| 3543 } |
3216 | 3544 |
3217 int TranslatedFrame::GetValueCount() { | 3545 int TranslatedFrame::GetValueCount() { |
3218 switch (kind()) { | 3546 switch (kind()) { |
3219 case kFunction: { | 3547 case kFunction: { |
3220 int parameter_count = | 3548 int parameter_count = |
3221 raw_shared_info_->internal_formal_parameter_count() + 1; | 3549 raw_shared_info_->internal_formal_parameter_count() + 1; |
3222 // + 1 for function. | 3550 // + 1 for function. |
3223 return height_ + parameter_count + 1; | 3551 return height_ + parameter_count + 1; |
3224 } | 3552 } |
3225 | 3553 |
3226 case kInterpretedFunction: { | 3554 case kInterpretedFunction: { |
3227 int parameter_count = | 3555 int parameter_count = |
3228 raw_shared_info_->internal_formal_parameter_count() + 1; | 3556 raw_shared_info_->internal_formal_parameter_count() + 1; |
3229 // + 2 for function and context. | 3557 // + 2 for function and context. |
3230 return height_ + parameter_count + 2; | 3558 return height_ + parameter_count + 2; |
3231 } | 3559 } |
3232 | 3560 |
3233 case kGetter: | 3561 case kGetter: |
3234 return 2; // Function and receiver. | 3562 return 2; // Function and receiver. |
3235 | 3563 |
3236 case kSetter: | 3564 case kSetter: |
3237 return 3; // Function, receiver and the value to set. | 3565 return 3; // Function, receiver and the value to set. |
3238 | 3566 |
3239 case kArgumentsAdaptor: | 3567 case kArgumentsAdaptor: |
3240 case kConstructStub: | 3568 case kConstructStub: |
| 3569 case kBuiltinContinuation: |
| 3570 case kJavaScriptBuiltinContinuation: |
3241 return 1 + height_; | 3571 return 1 + height_; |
3242 | 3572 |
3243 case kTailCallerFunction: | 3573 case kTailCallerFunction: |
3244 return 1; // Function. | 3574 return 1; // Function. |
3245 | 3575 |
3246 case kCompiledStub: | 3576 case kCompiledStub: |
3247 return height_; | 3577 return height_; |
3248 | 3578 |
3249 case kInvalid: | 3579 case kInvalid: |
3250 UNREACHABLE(); | 3580 UNREACHABLE(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3334 if (trace_file != nullptr) { | 3664 if (trace_file != nullptr) { |
3335 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3665 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3336 PrintF(trace_file, " reading construct stub frame %s", name.get()); | 3666 PrintF(trace_file, " reading construct stub frame %s", name.get()); |
3337 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", | 3667 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
3338 bailout_id.ToInt(), height); | 3668 bailout_id.ToInt(), height); |
3339 } | 3669 } |
3340 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, | 3670 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, |
3341 height); | 3671 height); |
3342 } | 3672 } |
3343 | 3673 |
| 3674 case Translation::BUILTIN_CONTINUATION_FRAME: { |
| 3675 BailoutId bailout_id = BailoutId(iterator->Next()); |
| 3676 SharedFunctionInfo* shared_info = |
| 3677 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3678 int height = iterator->Next(); |
| 3679 if (trace_file != nullptr) { |
| 3680 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
| 3681 PrintF(trace_file, " reading builtin continuation frame %s", |
| 3682 name.get()); |
| 3683 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
| 3684 bailout_id.ToInt(), height); |
| 3685 } |
| 3686 return TranslatedFrame::BuiltinContinuationFrame(bailout_id, shared_info, |
| 3687 height); |
| 3688 } |
| 3689 |
| 3690 case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: { |
| 3691 BailoutId bailout_id = BailoutId(iterator->Next()); |
| 3692 SharedFunctionInfo* shared_info = |
| 3693 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3694 int height = iterator->Next(); |
| 3695 if (trace_file != nullptr) { |
| 3696 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
| 3697 PrintF(trace_file, " reading JavaScript builtin continuation frame %s", |
| 3698 name.get()); |
| 3699 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
| 3700 bailout_id.ToInt(), height); |
| 3701 } |
| 3702 return TranslatedFrame::JavaScriptBuiltinContinuationFrame( |
| 3703 bailout_id, shared_info, height + 1); |
| 3704 } |
| 3705 |
3344 case Translation::GETTER_STUB_FRAME: { | 3706 case Translation::GETTER_STUB_FRAME: { |
3345 SharedFunctionInfo* shared_info = | 3707 SharedFunctionInfo* shared_info = |
3346 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 3708 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
3347 if (trace_file != nullptr) { | 3709 if (trace_file != nullptr) { |
3348 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3710 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3349 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); | 3711 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); |
3350 } | 3712 } |
3351 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, | 3713 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, |
3352 shared_info); | 3714 shared_info); |
3353 } | 3715 } |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3502 switch (opcode) { | 3864 switch (opcode) { |
3503 case Translation::BEGIN: | 3865 case Translation::BEGIN: |
3504 case Translation::JS_FRAME: | 3866 case Translation::JS_FRAME: |
3505 case Translation::INTERPRETED_FRAME: | 3867 case Translation::INTERPRETED_FRAME: |
3506 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3868 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
3507 case Translation::TAIL_CALLER_FRAME: | 3869 case Translation::TAIL_CALLER_FRAME: |
3508 case Translation::CONSTRUCT_STUB_FRAME: | 3870 case Translation::CONSTRUCT_STUB_FRAME: |
3509 case Translation::GETTER_STUB_FRAME: | 3871 case Translation::GETTER_STUB_FRAME: |
3510 case Translation::SETTER_STUB_FRAME: | 3872 case Translation::SETTER_STUB_FRAME: |
3511 case Translation::COMPILED_STUB_FRAME: | 3873 case Translation::COMPILED_STUB_FRAME: |
| 3874 case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: |
| 3875 case Translation::BUILTIN_CONTINUATION_FRAME: |
3512 // Peeled off before getting here. | 3876 // Peeled off before getting here. |
3513 break; | 3877 break; |
3514 | 3878 |
3515 case Translation::DUPLICATED_OBJECT: { | 3879 case Translation::DUPLICATED_OBJECT: { |
3516 int object_id = iterator->Next(); | 3880 int object_id = iterator->Next(); |
3517 if (trace_file != nullptr) { | 3881 if (trace_file != nullptr) { |
3518 PrintF(trace_file, "duplicated object #%d", object_id); | 3882 PrintF(trace_file, "duplicated object #%d", object_id); |
3519 } | 3883 } |
3520 object_positions_.push_back(object_positions_[object_id]); | 3884 object_positions_.push_back(object_positions_[object_id]); |
3521 TranslatedValue translated_value = | 3885 TranslatedValue translated_value = |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4456 CHECK(value_info->IsMaterializedObject()); | 4820 CHECK(value_info->IsMaterializedObject()); |
4457 | 4821 |
4458 value_info->value_ = | 4822 value_info->value_ = |
4459 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4823 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4460 } | 4824 } |
4461 } | 4825 } |
4462 } | 4826 } |
4463 | 4827 |
4464 } // namespace internal | 4828 } // namespace internal |
4465 } // namespace v8 | 4829 } // namespace v8 |
OLD | NEW |