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 + |
| 2246 TYPED_FRAME_SIZE(2 + allocatable_register_count); // For destination |
| 2247 // builtin code and |
| 2248 // registers |
| 2249 |
| 2250 // Validate types of parameters. They must all be tagged except for argc for |
| 2251 // JS builtins. |
| 2252 bool has_argc = false; |
| 2253 for (int i = 0; i < register_parameter_count; ++i) { |
| 2254 MachineType type = continuation_descriptor.GetParameterType(i); |
| 2255 int code = continuation_descriptor.GetRegisterParameter(i).code(); |
| 2256 // Only tagged and int32 arguments are supported, and int32 only for the |
| 2257 // arguments count on JavaScript builtins. |
| 2258 if (type == MachineType::Int32()) { |
| 2259 CHECK_EQ(code, kJavaScriptCallArgCountRegister.code()); |
| 2260 has_argc = true; |
| 2261 } else { |
| 2262 // Any other argument must be a tagged value. |
| 2263 CHECK(IsAnyTagged(type.representation())); |
| 2264 } |
| 2265 } |
| 2266 CHECK_EQ(java_script_builtin, has_argc); |
| 2267 |
| 2268 if (trace_scope_ != NULL) { |
| 2269 PrintF(trace_scope_->file(), |
| 2270 " translating BuiltinContinuation to %s, stack param count %d\n", |
| 2271 Builtins::name(builtin_name), stack_param_count); |
| 2272 } |
| 2273 |
| 2274 unsigned output_frame_offset = output_frame_size; |
| 2275 FrameDescription* output_frame = |
| 2276 new (output_frame_size) FrameDescription(output_frame_size); |
| 2277 output_[frame_index] = output_frame; |
| 2278 |
| 2279 // The top address of the frame is computed from the previous frame's top and |
| 2280 // this frame's size. |
| 2281 intptr_t top_address; |
| 2282 if (is_bottommost) { |
| 2283 top_address = caller_frame_top_ - output_frame_size; |
| 2284 } else { |
| 2285 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 2286 } |
| 2287 output_frame->SetTop(top_address); |
| 2288 |
| 2289 output_frame->SetState( |
| 2290 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); |
| 2291 |
| 2292 // Get the possible JSFunction for the case that |
| 2293 intptr_t maybe_function = |
| 2294 reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2295 ++value_iterator; |
| 2296 |
| 2297 std::vector<intptr_t> register_values; |
| 2298 int total_registers = config->num_general_registers(); |
| 2299 register_values.resize(total_registers, 0); |
| 2300 for (int i = 0; i < total_registers; ++i) { |
| 2301 register_values[i] = 0; |
| 2302 } |
| 2303 |
| 2304 intptr_t value; |
| 2305 |
| 2306 Register result_reg = FullCodeGenerator::result_register(); |
| 2307 if (must_handle_result) { |
| 2308 value = input_->GetRegister(result_reg.code()); |
| 2309 } else { |
| 2310 value = reinterpret_cast<intptr_t>(isolate()->heap()->undefined_value()); |
| 2311 } |
| 2312 output_frame->SetRegister(result_reg.code(), value); |
| 2313 |
| 2314 int translated_stack_parameters = |
| 2315 must_handle_result ? stack_param_count - 1 : stack_param_count; |
| 2316 |
| 2317 for (int i = 0; i < translated_stack_parameters; ++i) { |
| 2318 output_frame_offset -= kPointerSize; |
| 2319 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 2320 output_frame_offset); |
| 2321 } |
| 2322 |
| 2323 if (must_handle_result) { |
| 2324 output_frame_offset -= kPointerSize; |
| 2325 WriteValueToOutput(isolate()->heap()->the_hole_value(), input_index, |
| 2326 frame_index, output_frame_offset, |
| 2327 "placeholder for return result on lazy deopt "); |
| 2328 } |
| 2329 |
| 2330 for (int i = 0; i < register_parameter_count; ++i) { |
| 2331 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2332 int code = continuation_descriptor.GetRegisterParameter(i).code(); |
| 2333 register_values[code] = value; |
| 2334 ++input_index; |
| 2335 ++value_iterator; |
| 2336 } |
| 2337 |
| 2338 // The context register is always implicit in the CallInterfaceDescriptor but |
| 2339 // its register must be explicitly set when continuing to the builtin. Make |
| 2340 // sure that it's harvested from the translation and copied into the register |
| 2341 // set (it was automatically added at the end of the FrameState by the |
| 2342 // instruction selector). |
| 2343 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2344 register_values[kContextRegister.code()] = value; |
| 2345 output_frame->SetContext(value); |
| 2346 output_frame->SetRegister(kContextRegister.code(), value); |
| 2347 ++input_index; |
| 2348 ++value_iterator; |
| 2349 |
| 2350 // Set caller's PC (JSFunction continuation). |
| 2351 output_frame_offset -= kPCOnStackSize; |
| 2352 if (is_bottommost) { |
| 2353 value = caller_pc_; |
| 2354 } else { |
| 2355 value = output_[frame_index - 1]->GetPc(); |
| 2356 } |
| 2357 output_frame->SetCallerPc(output_frame_offset, value); |
| 2358 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2359 "caller's pc\n"); |
| 2360 |
| 2361 // Read caller's FP from the previous frame, and set this frame's FP. |
| 2362 output_frame_offset -= kFPOnStackSize; |
| 2363 if (is_bottommost) { |
| 2364 value = caller_fp_; |
| 2365 } else { |
| 2366 value = output_[frame_index - 1]->GetFp(); |
| 2367 } |
| 2368 output_frame->SetCallerFp(output_frame_offset, value); |
| 2369 intptr_t fp_value = top_address + output_frame_offset; |
| 2370 output_frame->SetFp(fp_value); |
| 2371 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2372 "caller's fp\n"); |
| 2373 |
| 2374 if (FLAG_enable_embedded_constant_pool) { |
| 2375 // Read the caller's constant pool from the previous frame. |
| 2376 output_frame_offset -= kPointerSize; |
| 2377 if (is_bottommost) { |
| 2378 value = caller_constant_pool_; |
| 2379 } else { |
| 2380 value = output_[frame_index - 1]->GetConstantPool(); |
| 2381 } |
| 2382 output_frame->SetCallerConstantPool(output_frame_offset, value); |
| 2383 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2384 "caller's constant_pool\n"); |
| 2385 } |
| 2386 |
| 2387 // A marker value is used in place of the context. |
| 2388 output_frame_offset -= kPointerSize; |
| 2389 intptr_t marker = |
| 2390 java_script_builtin |
| 2391 ? StackFrame::TypeToMarker( |
| 2392 StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION) |
| 2393 : StackFrame::TypeToMarker(StackFrame::BUILTIN_CONTINUATION); |
| 2394 output_frame->SetFrameSlot(output_frame_offset, marker); |
| 2395 DebugPrintOutputSlot(marker, frame_index, output_frame_offset, |
| 2396 "context (builtin continuation sentinel)\n"); |
| 2397 |
| 2398 output_frame_offset -= kPointerSize; |
| 2399 value = java_script_builtin ? maybe_function : 0; |
| 2400 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2401 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2402 java_script_builtin ? "JSFunction\n" : "unused\n"); |
| 2403 |
| 2404 // The builtin to continue to |
| 2405 output_frame_offset -= kPointerSize; |
| 2406 value = reinterpret_cast<intptr_t>(builtin); |
| 2407 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2408 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2409 "builtin address\n"); |
| 2410 |
| 2411 for (int i = 0; i < allocatable_register_count; ++i) { |
| 2412 output_frame_offset -= kPointerSize; |
| 2413 int code = config->GetAllocatableGeneralCode(i); |
| 2414 value = register_values[code]; |
| 2415 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2416 if (trace_scope_ != nullptr) { |
| 2417 ScopedVector<char> str(128); |
| 2418 if (java_script_builtin && |
| 2419 code == kJavaScriptCallArgCountRegister.code()) { |
| 2420 SNPrintF( |
| 2421 str, |
| 2422 "tagged argument count %s (will be untagged by continuation)\n", |
| 2423 config->GetGeneralRegisterName(code)); |
| 2424 } else { |
| 2425 SNPrintF(str, "builtin register argument %s\n", |
| 2426 config->GetGeneralRegisterName(code)); |
| 2427 } |
| 2428 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2429 str.start()); |
| 2430 } |
| 2431 } |
| 2432 |
| 2433 // Ensure the frame pointer register points to the callee's frame. The builtin |
| 2434 // will build its own frame once we continue to it. |
| 2435 Register fp_reg = JavaScriptFrame::fp_register(); |
| 2436 output_frame->SetRegister(fp_reg.code(), output_[frame_index - 1]->GetFp()); |
| 2437 |
| 2438 Code* continue_to_builtin = |
| 2439 java_script_builtin |
| 2440 ? (must_handle_result |
| 2441 ? isolate()->builtins()->builtin( |
| 2442 Builtins::kContinueToJavaScriptBuiltinWithResult) |
| 2443 : isolate()->builtins()->builtin( |
| 2444 Builtins::kContinueToJavaScriptBuiltin)) |
| 2445 : (must_handle_result |
| 2446 ? isolate()->builtins()->builtin( |
| 2447 Builtins::kContinueToCodeStubBuiltinWithResult) |
| 2448 : isolate()->builtins()->builtin( |
| 2449 Builtins::kContinueToCodeStubBuiltin)); |
| 2450 output_frame->SetPc( |
| 2451 reinterpret_cast<intptr_t>(continue_to_builtin->instruction_start())); |
| 2452 |
| 2453 Code* continuation = |
| 2454 isolate()->builtins()->builtin(Builtins::kNotifyBuiltinContinuation); |
| 2455 output_frame->SetContinuation( |
| 2456 reinterpret_cast<intptr_t>(continuation->entry())); |
| 2457 } |
2164 | 2458 |
2165 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 2459 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
2166 // Walk to the last JavaScript output frame to find out if it has | 2460 // Walk to the last JavaScript output frame to find out if it has |
2167 // adapted arguments. | 2461 // adapted arguments. |
2168 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 2462 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
2169 if (frame_index != 0) it->Advance(); | 2463 if (frame_index != 0) it->Advance(); |
2170 } | 2464 } |
2171 translated_state_.Prepare(it->frame()->has_adapted_arguments(), | 2465 translated_state_.Prepare(it->frame()->has_adapted_arguments(), |
2172 reinterpret_cast<Address>(stack_fp_)); | 2466 reinterpret_cast<Address>(stack_fp_)); |
2173 | 2467 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2398 return is_negative ? -result : result; | 2692 return is_negative ? -result : result; |
2399 } | 2693 } |
2400 | 2694 |
2401 | 2695 |
2402 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { | 2696 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { |
2403 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); | 2697 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); |
2404 contents_.CopyTo(result->GetDataStartAddress()); | 2698 contents_.CopyTo(result->GetDataStartAddress()); |
2405 return result; | 2699 return result; |
2406 } | 2700 } |
2407 | 2701 |
| 2702 void Translation::BeginBuiltinContinuationFrame(BailoutId bailout_id, |
| 2703 int literal_id, |
| 2704 unsigned height) { |
| 2705 buffer_->Add(BUILTIN_CONTINUATION_FRAME); |
| 2706 buffer_->Add(bailout_id.ToInt()); |
| 2707 buffer_->Add(literal_id); |
| 2708 buffer_->Add(height); |
| 2709 } |
| 2710 |
| 2711 void Translation::BeginJavaScriptBuiltinContinuationFrame(BailoutId bailout_id, |
| 2712 int literal_id, |
| 2713 unsigned height) { |
| 2714 buffer_->Add(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME); |
| 2715 buffer_->Add(bailout_id.ToInt()); |
| 2716 buffer_->Add(literal_id); |
| 2717 buffer_->Add(height); |
| 2718 } |
| 2719 |
2408 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, | 2720 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, |
2409 unsigned height) { | 2721 unsigned height) { |
2410 buffer_->Add(CONSTRUCT_STUB_FRAME); | 2722 buffer_->Add(CONSTRUCT_STUB_FRAME); |
2411 buffer_->Add(bailout_id.ToInt()); | 2723 buffer_->Add(bailout_id.ToInt()); |
2412 buffer_->Add(literal_id); | 2724 buffer_->Add(literal_id); |
2413 buffer_->Add(height); | 2725 buffer_->Add(height); |
2414 } | 2726 } |
2415 | 2727 |
2416 | 2728 |
2417 void Translation::BeginGetterStubFrame(int literal_id) { | 2729 void Translation::BeginGetterStubFrame(int literal_id) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2600 case LITERAL: | 2912 case LITERAL: |
2601 case COMPILED_STUB_FRAME: | 2913 case COMPILED_STUB_FRAME: |
2602 case TAIL_CALLER_FRAME: | 2914 case TAIL_CALLER_FRAME: |
2603 return 1; | 2915 return 1; |
2604 case BEGIN: | 2916 case BEGIN: |
2605 case ARGUMENTS_ADAPTOR_FRAME: | 2917 case ARGUMENTS_ADAPTOR_FRAME: |
2606 return 2; | 2918 return 2; |
2607 case JS_FRAME: | 2919 case JS_FRAME: |
2608 case INTERPRETED_FRAME: | 2920 case INTERPRETED_FRAME: |
2609 case CONSTRUCT_STUB_FRAME: | 2921 case CONSTRUCT_STUB_FRAME: |
| 2922 case BUILTIN_CONTINUATION_FRAME: |
| 2923 case JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: |
2610 return 3; | 2924 return 3; |
2611 case ARGUMENTS_ELEMENTS: | 2925 case ARGUMENTS_ELEMENTS: |
2612 case ARGUMENTS_LENGTH: | 2926 case ARGUMENTS_LENGTH: |
2613 return 1; | 2927 return 1; |
2614 } | 2928 } |
2615 FATAL("Unexpected translation type"); | 2929 FATAL("Unexpected translation type"); |
2616 return -1; | 2930 return -1; |
2617 } | 2931 } |
2618 | 2932 |
2619 | 2933 |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3206 } | 3520 } |
3207 | 3521 |
3208 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 3522 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
3209 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { | 3523 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
3210 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, | 3524 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, |
3211 height); | 3525 height); |
3212 frame.node_id_ = bailout_id; | 3526 frame.node_id_ = bailout_id; |
3213 return frame; | 3527 return frame; |
3214 } | 3528 } |
3215 | 3529 |
| 3530 TranslatedFrame TranslatedFrame::BuiltinContinuationFrame( |
| 3531 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
| 3532 base::OS::DebugBreak(); |
| 3533 TranslatedFrame frame(kBuiltinContinuation, shared_info->GetIsolate(), |
| 3534 shared_info, height); |
| 3535 frame.node_id_ = bailout_id; |
| 3536 return frame; |
| 3537 } |
| 3538 |
| 3539 TranslatedFrame TranslatedFrame::JavaScriptBuiltinContinuationFrame( |
| 3540 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
| 3541 TranslatedFrame frame(kJavaScriptBuiltinContinuation, |
| 3542 shared_info->GetIsolate(), shared_info, height); |
| 3543 frame.node_id_ = bailout_id; |
| 3544 return frame; |
| 3545 } |
3216 | 3546 |
3217 int TranslatedFrame::GetValueCount() { | 3547 int TranslatedFrame::GetValueCount() { |
3218 switch (kind()) { | 3548 switch (kind()) { |
3219 case kFunction: { | 3549 case kFunction: { |
3220 int parameter_count = | 3550 int parameter_count = |
3221 raw_shared_info_->internal_formal_parameter_count() + 1; | 3551 raw_shared_info_->internal_formal_parameter_count() + 1; |
3222 // + 1 for function. | 3552 // + 1 for function. |
3223 return height_ + parameter_count + 1; | 3553 return height_ + parameter_count + 1; |
3224 } | 3554 } |
3225 | 3555 |
3226 case kInterpretedFunction: { | 3556 case kInterpretedFunction: { |
3227 int parameter_count = | 3557 int parameter_count = |
3228 raw_shared_info_->internal_formal_parameter_count() + 1; | 3558 raw_shared_info_->internal_formal_parameter_count() + 1; |
3229 // + 2 for function and context. | 3559 // + 2 for function and context. |
3230 return height_ + parameter_count + 2; | 3560 return height_ + parameter_count + 2; |
3231 } | 3561 } |
3232 | 3562 |
3233 case kGetter: | 3563 case kGetter: |
3234 return 2; // Function and receiver. | 3564 return 2; // Function and receiver. |
3235 | 3565 |
3236 case kSetter: | 3566 case kSetter: |
3237 return 3; // Function, receiver and the value to set. | 3567 return 3; // Function, receiver and the value to set. |
3238 | 3568 |
3239 case kArgumentsAdaptor: | 3569 case kArgumentsAdaptor: |
3240 case kConstructStub: | 3570 case kConstructStub: |
| 3571 case kBuiltinContinuation: |
| 3572 case kJavaScriptBuiltinContinuation: |
3241 return 1 + height_; | 3573 return 1 + height_; |
3242 | 3574 |
3243 case kTailCallerFunction: | 3575 case kTailCallerFunction: |
3244 return 1; // Function. | 3576 return 1; // Function. |
3245 | 3577 |
3246 case kCompiledStub: | 3578 case kCompiledStub: |
3247 return height_; | 3579 return height_; |
3248 | 3580 |
3249 case kInvalid: | 3581 case kInvalid: |
3250 UNREACHABLE(); | 3582 UNREACHABLE(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3334 if (trace_file != nullptr) { | 3666 if (trace_file != nullptr) { |
3335 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3667 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3336 PrintF(trace_file, " reading construct stub frame %s", name.get()); | 3668 PrintF(trace_file, " reading construct stub frame %s", name.get()); |
3337 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", | 3669 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
3338 bailout_id.ToInt(), height); | 3670 bailout_id.ToInt(), height); |
3339 } | 3671 } |
3340 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, | 3672 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, |
3341 height); | 3673 height); |
3342 } | 3674 } |
3343 | 3675 |
| 3676 case Translation::BUILTIN_CONTINUATION_FRAME: { |
| 3677 BailoutId bailout_id = BailoutId(iterator->Next()); |
| 3678 SharedFunctionInfo* shared_info = |
| 3679 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3680 int height = iterator->Next(); |
| 3681 if (trace_file != nullptr) { |
| 3682 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
| 3683 PrintF(trace_file, " reading builtin continuation frame %s", |
| 3684 name.get()); |
| 3685 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
| 3686 bailout_id.ToInt(), height); |
| 3687 } |
| 3688 return TranslatedFrame::BuiltinContinuationFrame(bailout_id, shared_info, |
| 3689 height); |
| 3690 } |
| 3691 |
| 3692 case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: { |
| 3693 BailoutId bailout_id = BailoutId(iterator->Next()); |
| 3694 SharedFunctionInfo* shared_info = |
| 3695 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3696 int height = iterator->Next(); |
| 3697 if (trace_file != nullptr) { |
| 3698 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
| 3699 PrintF(trace_file, " reading JavaScript builtin continuation frame %s", |
| 3700 name.get()); |
| 3701 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
| 3702 bailout_id.ToInt(), height); |
| 3703 } |
| 3704 return TranslatedFrame::JavaScriptBuiltinContinuationFrame( |
| 3705 bailout_id, shared_info, height + 1); |
| 3706 } |
| 3707 |
3344 case Translation::GETTER_STUB_FRAME: { | 3708 case Translation::GETTER_STUB_FRAME: { |
3345 SharedFunctionInfo* shared_info = | 3709 SharedFunctionInfo* shared_info = |
3346 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 3710 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
3347 if (trace_file != nullptr) { | 3711 if (trace_file != nullptr) { |
3348 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3712 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3349 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); | 3713 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); |
3350 } | 3714 } |
3351 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, | 3715 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, |
3352 shared_info); | 3716 shared_info); |
3353 } | 3717 } |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3502 switch (opcode) { | 3866 switch (opcode) { |
3503 case Translation::BEGIN: | 3867 case Translation::BEGIN: |
3504 case Translation::JS_FRAME: | 3868 case Translation::JS_FRAME: |
3505 case Translation::INTERPRETED_FRAME: | 3869 case Translation::INTERPRETED_FRAME: |
3506 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3870 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
3507 case Translation::TAIL_CALLER_FRAME: | 3871 case Translation::TAIL_CALLER_FRAME: |
3508 case Translation::CONSTRUCT_STUB_FRAME: | 3872 case Translation::CONSTRUCT_STUB_FRAME: |
3509 case Translation::GETTER_STUB_FRAME: | 3873 case Translation::GETTER_STUB_FRAME: |
3510 case Translation::SETTER_STUB_FRAME: | 3874 case Translation::SETTER_STUB_FRAME: |
3511 case Translation::COMPILED_STUB_FRAME: | 3875 case Translation::COMPILED_STUB_FRAME: |
| 3876 case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: |
| 3877 case Translation::BUILTIN_CONTINUATION_FRAME: |
3512 // Peeled off before getting here. | 3878 // Peeled off before getting here. |
3513 break; | 3879 break; |
3514 | 3880 |
3515 case Translation::DUPLICATED_OBJECT: { | 3881 case Translation::DUPLICATED_OBJECT: { |
3516 int object_id = iterator->Next(); | 3882 int object_id = iterator->Next(); |
3517 if (trace_file != nullptr) { | 3883 if (trace_file != nullptr) { |
3518 PrintF(trace_file, "duplicated object #%d", object_id); | 3884 PrintF(trace_file, "duplicated object #%d", object_id); |
3519 } | 3885 } |
3520 object_positions_.push_back(object_positions_[object_id]); | 3886 object_positions_.push_back(object_positions_[object_id]); |
3521 TranslatedValue translated_value = | 3887 TranslatedValue translated_value = |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4456 CHECK(value_info->IsMaterializedObject()); | 4822 CHECK(value_info->IsMaterializedObject()); |
4457 | 4823 |
4458 value_info->value_ = | 4824 value_info->value_ = |
4459 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4825 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4460 } | 4826 } |
4461 } | 4827 } |
4462 } | 4828 } |
4463 | 4829 |
4464 } // namespace internal | 4830 } // namespace internal |
4465 } // namespace v8 | 4831 } // namespace v8 |
OLD | NEW |