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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 break; | 815 break; |
816 case TranslatedFrame::kGetter: | 816 case TranslatedFrame::kGetter: |
817 DoComputeAccessorStubFrame(translated_frame, frame_index, false); | 817 DoComputeAccessorStubFrame(translated_frame, frame_index, false); |
818 break; | 818 break; |
819 case TranslatedFrame::kSetter: | 819 case TranslatedFrame::kSetter: |
820 DoComputeAccessorStubFrame(translated_frame, frame_index, true); | 820 DoComputeAccessorStubFrame(translated_frame, frame_index, true); |
821 break; | 821 break; |
822 case TranslatedFrame::kCompiledStub: | 822 case TranslatedFrame::kCompiledStub: |
823 DoComputeCompiledStubFrame(translated_frame, frame_index); | 823 DoComputeCompiledStubFrame(translated_frame, frame_index); |
824 break; | 824 break; |
| 825 case TranslatedFrame::kBuiltinContinuation: |
| 826 DoComputeBuiltinContinuation(translated_frame, frame_index); |
| 827 break; |
825 case TranslatedFrame::kInvalid: | 828 case TranslatedFrame::kInvalid: |
826 FATAL("invalid frame"); | 829 FATAL("invalid frame"); |
827 break; | 830 break; |
828 } | 831 } |
829 } | 832 } |
830 | 833 |
831 // Print some helpful diagnostic information. | 834 // Print some helpful diagnostic information. |
832 if (trace_scope_ != NULL) { | 835 if (trace_scope_ != NULL) { |
833 double ms = timer.Elapsed().InMillisecondsF(); | 836 double ms = timer.Elapsed().InMillisecondsF(); |
834 int index = output_count_ - 1; // Index of the topmost frame. | 837 int index = output_count_ - 1; // Index of the topmost frame. |
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | 2146 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
2144 } | 2147 } |
2145 output_frame->SetState( | 2148 output_frame->SetState( |
2146 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); | 2149 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); |
2147 Code* notify_failure = | 2150 Code* notify_failure = |
2148 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); | 2151 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); |
2149 output_frame->SetContinuation( | 2152 output_frame->SetContinuation( |
2150 reinterpret_cast<intptr_t>(notify_failure->entry())); | 2153 reinterpret_cast<intptr_t>(notify_failure->entry())); |
2151 } | 2154 } |
2152 | 2155 |
| 2156 // BuiltinContinuationFrames capture the machine state that is expected as input |
| 2157 // to a builtin, including both input register values and stack parameters. When |
| 2158 // the frame is reactivated (i.e. the frame below it returns), a |
| 2159 // ContinueToBuiltin stub restores the register state from the frame and tail |
| 2160 // calls to the actual target builtin, making it appear that the stub had been |
| 2161 // directly called by the frame above it. The input values to populate the frame |
| 2162 // are taken from the deopt's FrameState. |
| 2163 // |
| 2164 // Frame translation happens in two modes, EAGER and LAZY. In EAGER mode, all of |
| 2165 // the parameters to the Builtin are explicitly specified in the TurboFan |
| 2166 // FrameState node. In LAZY mode, there is always one fewer parameters specified |
| 2167 // in the FrameState than expected by the Builtin. In that case, construction of |
| 2168 // BuiltinContinuationFrame adds the final missing parameter during |
| 2169 // deoptimization, and that parameter is always on the stack and contains the |
| 2170 // value returned from the callee of the call site triggering the LAZY deopt |
| 2171 // (e.g. rax on x64). This requires that continuation Builtins for LAZY deopts |
| 2172 // must have at least one stack parameter. |
| 2173 // |
| 2174 // TO |
| 2175 // | .... | |
| 2176 // +-------------------------+ |
| 2177 // | builtin param 0 |<- FrameState input value n becomes |
| 2178 // +-------------------------+ |
| 2179 // | ... | |
| 2180 // +-------------------------+ |
| 2181 // | builtin param m |<- FrameState input value n+m-1, or in |
| 2182 // +-------------------------+ the LAZY case, return LAZY result value |
| 2183 // | ContinueToBuiltin entry | |
| 2184 // +-------------------------+ |
| 2185 // | | saved frame (FP) | |
| 2186 // | +=========================+<- fpreg |
| 2187 // | |constant pool (if ool_cp)| |
| 2188 // v +-------------------------+ |
| 2189 // |BUILTIN_CONTINUATION mark| |
| 2190 // +-------------------------+ |
| 2191 // | JS Builtin code object | |
| 2192 // +-------------------------+ |
| 2193 // | builtin input GPR reg0 |<- populated from deopt FrameState using |
| 2194 // +-------------------------+ the builtin's CallInterfaceDescriptor |
| 2195 // | ... | to map a FrameState's 0..n-1 inputs to |
| 2196 // +-------------------------+ the builtin's n input register params. |
| 2197 // | builtin input GPR regn | |
| 2198 // |-------------------------|<- spreg |
| 2199 // |
| 2200 void Deoptimizer::DoComputeBuiltinContinuation( |
| 2201 TranslatedFrame* translated_frame, int frame_index) { |
| 2202 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 2203 int input_index = 0; |
| 2204 |
| 2205 // The output frame must have room for all of the parameters that need to be |
| 2206 // passed to the builtin continuation. |
| 2207 int height_in_words = translated_frame->height(); |
| 2208 |
| 2209 BailoutId bailout_id = translated_frame->node_id(); |
| 2210 Builtins::Name builtin_name = Builtins::GetBuiltinFromBailoutId(bailout_id); |
| 2211 Code* builtin = isolate()->builtins()->builtin(builtin_name); |
| 2212 Callable continuation_callable = |
| 2213 Builtins::CallableFor(isolate(), builtin_name); |
| 2214 CallInterfaceDescriptor continuation_descriptor = |
| 2215 continuation_callable.descriptor(); |
| 2216 |
| 2217 bool is_bottommost = (0 == frame_index); |
| 2218 bool is_topmost = (output_count_ - 1 == frame_index); |
| 2219 bool must_handle_result = !is_topmost || bailout_type_ == LAZY; |
| 2220 |
| 2221 const RegisterConfiguration* config(RegisterConfiguration::Turbofan()); |
| 2222 int allocatable_register_count = config->num_allocatable_general_registers(); |
| 2223 int register_parameter_count = |
| 2224 continuation_descriptor.GetRegisterParameterCount(); |
| 2225 // Make sure to account for the context by removing it from the register |
| 2226 // parameter count. |
| 2227 int stack_param_count = height_in_words - register_parameter_count - 1; |
| 2228 if (must_handle_result) stack_param_count++; |
| 2229 int output_frame_size = |
| 2230 kPointerSize * stack_param_count + |
| 2231 TYPED_FRAME_SIZE(1 + allocatable_register_count); // For destination |
| 2232 // builtin code and |
| 2233 // registers |
| 2234 if (trace_scope_ != NULL) { |
| 2235 PrintF(trace_scope_->file(), |
| 2236 " translating BuiltinContinuation to %s, stack param count %d\n", |
| 2237 Builtins::name(builtin_name), stack_param_count); |
| 2238 } |
| 2239 |
| 2240 unsigned output_frame_offset = output_frame_size; |
| 2241 FrameDescription* output_frame = |
| 2242 new (output_frame_size) FrameDescription(output_frame_size); |
| 2243 output_[frame_index] = output_frame; |
| 2244 |
| 2245 // The top address of the frame is computed from the previous frame's top and |
| 2246 // this frame's size. |
| 2247 intptr_t top_address; |
| 2248 if (is_bottommost) { |
| 2249 top_address = caller_frame_top_ - output_frame_size; |
| 2250 } else { |
| 2251 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 2252 } |
| 2253 output_frame->SetTop(top_address); |
| 2254 |
| 2255 output_frame->SetState( |
| 2256 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS))); |
| 2257 |
| 2258 // Get the JSFunction |
| 2259 Object* maybe_function = value_iterator->GetRawValue(); |
| 2260 JSFunction* function = JSFunction::cast(maybe_function); |
| 2261 USE(function); |
| 2262 ++value_iterator; |
| 2263 |
| 2264 std::vector<intptr_t> register_values; |
| 2265 int total_registers = config->num_general_registers(); |
| 2266 register_values.resize(total_registers, 0); |
| 2267 for (int i = 0; i < total_registers; ++i) { |
| 2268 register_values[i] = 0; |
| 2269 } |
| 2270 |
| 2271 bool java_script_builtin = false; |
| 2272 intptr_t value; |
| 2273 for (int i = 0; i < register_parameter_count; ++i) { |
| 2274 MachineType type = continuation_descriptor.GetParameterType(i); |
| 2275 int code = continuation_descriptor.GetRegisterParameter(i).code(); |
| 2276 // Only tagged and int32 arguments are supported, and int32 only for the |
| 2277 // arguments count on JavaScript builtins. |
| 2278 if (type == MachineType::Int32()) { |
| 2279 CHECK_EQ(code, kJavaScriptCallArgCountRegister.code()); |
| 2280 java_script_builtin = true; |
| 2281 } else { |
| 2282 // Any other argument must be a tagged value. |
| 2283 CHECK(IsAnyTagged(type.representation())); |
| 2284 } |
| 2285 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2286 register_values[code] = value; |
| 2287 ++input_index; |
| 2288 ++value_iterator; |
| 2289 } |
| 2290 |
| 2291 value = reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); |
| 2292 register_values[kContextRegister.code()] = value; |
| 2293 output_frame->SetContext(value); |
| 2294 output_frame->SetRegister(kContextRegister.code(), value); |
| 2295 ++input_index; |
| 2296 ++value_iterator; |
| 2297 |
| 2298 int translated_stack_parameters = |
| 2299 must_handle_result ? stack_param_count - 1 : stack_param_count; |
| 2300 |
| 2301 for (int i = 0; i < translated_stack_parameters; ++i) { |
| 2302 output_frame_offset -= kPointerSize; |
| 2303 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 2304 output_frame_offset); |
| 2305 } |
| 2306 |
| 2307 if (must_handle_result) { |
| 2308 output_frame_offset -= kPointerSize; |
| 2309 WriteValueToOutput(isolate()->heap()->the_hole_value(), input_index, |
| 2310 frame_index, output_frame_offset, |
| 2311 "placeholder for return result on lazy deopt "); |
| 2312 ++input_index; |
| 2313 ++value_iterator; |
| 2314 } |
| 2315 |
| 2316 // Set caller's PC (JSFunction continuation). |
| 2317 output_frame_offset -= kPCOnStackSize; |
| 2318 if (is_bottommost) { |
| 2319 value = caller_pc_; |
| 2320 } else { |
| 2321 value = output_[frame_index - 1]->GetPc(); |
| 2322 } |
| 2323 output_frame->SetCallerPc(output_frame_offset, value); |
| 2324 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2325 "caller's pc\n"); |
| 2326 |
| 2327 // Read caller's FP from the previous frame, and set this frame's FP. |
| 2328 output_frame_offset -= kFPOnStackSize; |
| 2329 if (is_bottommost) { |
| 2330 value = caller_fp_; |
| 2331 } else { |
| 2332 value = output_[frame_index - 1]->GetFp(); |
| 2333 } |
| 2334 output_frame->SetCallerFp(output_frame_offset, value); |
| 2335 intptr_t fp_value = top_address + output_frame_offset; |
| 2336 output_frame->SetFp(fp_value); |
| 2337 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2338 "caller's fp\n"); |
| 2339 |
| 2340 if (FLAG_enable_embedded_constant_pool) { |
| 2341 // Read the caller's constant pool from the previous frame. |
| 2342 output_frame_offset -= kPointerSize; |
| 2343 if (is_bottommost) { |
| 2344 value = caller_constant_pool_; |
| 2345 } else { |
| 2346 value = output_[frame_index - 1]->GetConstantPool(); |
| 2347 } |
| 2348 output_frame->SetCallerConstantPool(output_frame_offset, value); |
| 2349 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2350 "caller's constant_pool\n"); |
| 2351 } |
| 2352 |
| 2353 // A marker value is used in place of the context. |
| 2354 output_frame_offset -= kPointerSize; |
| 2355 intptr_t marker = StackFrame::TypeToMarker(StackFrame::BUILTIN_CONTINUATION); |
| 2356 output_frame->SetFrameSlot(output_frame_offset, marker); |
| 2357 DebugPrintOutputSlot(marker, frame_index, output_frame_offset, |
| 2358 "context (builtin continuation sentinel)\n"); |
| 2359 |
| 2360 // The builtin to continue to |
| 2361 output_frame_offset -= kPointerSize; |
| 2362 value = reinterpret_cast<intptr_t>(builtin); |
| 2363 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2364 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2365 "builtin address\n"); |
| 2366 |
| 2367 for (int i = 0; i < allocatable_register_count; ++i) { |
| 2368 output_frame_offset -= kPointerSize; |
| 2369 int code = config->GetAllocatableGeneralCode(i); |
| 2370 value = reinterpret_cast<intptr_t>(register_values[code]); |
| 2371 output_frame->SetFrameSlot(output_frame_offset, value); |
| 2372 if (trace_scope_ != nullptr) { |
| 2373 ScopedVector<char> str(128); |
| 2374 if (java_script_builtin && |
| 2375 code == kJavaScriptCallArgCountRegister.code()) { |
| 2376 SNPrintF( |
| 2377 str, |
| 2378 "tagged argument count %s (will be untagged by continuation)\n", |
| 2379 config->GetGeneralRegisterName(code)); |
| 2380 } else { |
| 2381 SNPrintF(str, "builtin register argument %s\n", |
| 2382 config->GetGeneralRegisterName(code)); |
| 2383 } |
| 2384 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 2385 str.start()); |
| 2386 } |
| 2387 } |
| 2388 |
| 2389 // Ensure the frame pointer register points to the callee's frame. The builtin |
| 2390 // will build its own frame once we continue to it. |
| 2391 Register fp_reg = JavaScriptFrame::fp_register(); |
| 2392 output_frame->SetRegister(fp_reg.code(), output_[frame_index - 1]->GetFp()); |
| 2393 |
| 2394 Code* continue_to_builtin = |
| 2395 java_script_builtin |
| 2396 ? (must_handle_result |
| 2397 ? isolate()->builtins()->builtin( |
| 2398 Builtins::kContinueToJavaScriptBuiltinWithResult) |
| 2399 : isolate()->builtins()->builtin( |
| 2400 Builtins::kContinueToJavaScriptBuiltin)) |
| 2401 : (must_handle_result |
| 2402 ? isolate()->builtins()->builtin( |
| 2403 Builtins::kContinueToCodeStubBuiltinWithResult) |
| 2404 : isolate()->builtins()->builtin( |
| 2405 Builtins::kContinueToCodeStubBuiltin)); |
| 2406 output_frame->SetPc( |
| 2407 reinterpret_cast<intptr_t>(continue_to_builtin->instruction_start())); |
| 2408 |
| 2409 Code* continuation = |
| 2410 isolate()->builtins()->builtin(Builtins::kNotifyBuiltinContinuation); |
| 2411 output_frame->SetContinuation( |
| 2412 reinterpret_cast<intptr_t>(continuation->entry())); |
| 2413 } |
2153 | 2414 |
2154 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 2415 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
2155 // Walk to the last JavaScript output frame to find out if it has | 2416 // Walk to the last JavaScript output frame to find out if it has |
2156 // adapted arguments. | 2417 // adapted arguments. |
2157 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 2418 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
2158 if (frame_index != 0) it->Advance(); | 2419 if (frame_index != 0) it->Advance(); |
2159 } | 2420 } |
2160 translated_state_.Prepare(it->frame()->has_adapted_arguments(), | 2421 translated_state_.Prepare(it->frame()->has_adapted_arguments(), |
2161 reinterpret_cast<Address>(stack_fp_)); | 2422 reinterpret_cast<Address>(stack_fp_)); |
2162 | 2423 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2381 return is_negative ? -result : result; | 2642 return is_negative ? -result : result; |
2382 } | 2643 } |
2383 | 2644 |
2384 | 2645 |
2385 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { | 2646 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) { |
2386 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); | 2647 Handle<ByteArray> result = factory->NewByteArray(CurrentIndex(), TENURED); |
2387 contents_.CopyTo(result->GetDataStartAddress()); | 2648 contents_.CopyTo(result->GetDataStartAddress()); |
2388 return result; | 2649 return result; |
2389 } | 2650 } |
2390 | 2651 |
| 2652 void Translation::BeginBuiltinContinuationFrame(BailoutId bailout_id, |
| 2653 int literal_id, |
| 2654 unsigned height) { |
| 2655 buffer_->Add(BUILTIN_CONTINUATION_FRAME); |
| 2656 buffer_->Add(bailout_id.ToInt()); |
| 2657 buffer_->Add(literal_id); |
| 2658 buffer_->Add(height); |
| 2659 } |
| 2660 |
2391 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, | 2661 void Translation::BeginConstructStubFrame(BailoutId bailout_id, int literal_id, |
2392 unsigned height) { | 2662 unsigned height) { |
2393 buffer_->Add(CONSTRUCT_STUB_FRAME); | 2663 buffer_->Add(CONSTRUCT_STUB_FRAME); |
2394 buffer_->Add(bailout_id.ToInt()); | 2664 buffer_->Add(bailout_id.ToInt()); |
2395 buffer_->Add(literal_id); | 2665 buffer_->Add(literal_id); |
2396 buffer_->Add(height); | 2666 buffer_->Add(height); |
2397 } | 2667 } |
2398 | 2668 |
2399 | 2669 |
2400 void Translation::BeginGetterStubFrame(int literal_id) { | 2670 void Translation::BeginGetterStubFrame(int literal_id) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 case LITERAL: | 2853 case LITERAL: |
2584 case COMPILED_STUB_FRAME: | 2854 case COMPILED_STUB_FRAME: |
2585 case TAIL_CALLER_FRAME: | 2855 case TAIL_CALLER_FRAME: |
2586 return 1; | 2856 return 1; |
2587 case BEGIN: | 2857 case BEGIN: |
2588 case ARGUMENTS_ADAPTOR_FRAME: | 2858 case ARGUMENTS_ADAPTOR_FRAME: |
2589 return 2; | 2859 return 2; |
2590 case JS_FRAME: | 2860 case JS_FRAME: |
2591 case INTERPRETED_FRAME: | 2861 case INTERPRETED_FRAME: |
2592 case CONSTRUCT_STUB_FRAME: | 2862 case CONSTRUCT_STUB_FRAME: |
| 2863 case BUILTIN_CONTINUATION_FRAME: |
2593 return 3; | 2864 return 3; |
2594 case ARGUMENTS_ELEMENTS: | 2865 case ARGUMENTS_ELEMENTS: |
2595 case ARGUMENTS_LENGTH: | 2866 case ARGUMENTS_LENGTH: |
2596 return 1; | 2867 return 1; |
2597 } | 2868 } |
2598 FATAL("Unexpected translation type"); | 2869 FATAL("Unexpected translation type"); |
2599 return -1; | 2870 return -1; |
2600 } | 2871 } |
2601 | 2872 |
2602 | 2873 |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 } | 3461 } |
3191 | 3462 |
3192 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 3463 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
3193 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { | 3464 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
3194 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, | 3465 TranslatedFrame frame(kConstructStub, shared_info->GetIsolate(), shared_info, |
3195 height); | 3466 height); |
3196 frame.node_id_ = bailout_id; | 3467 frame.node_id_ = bailout_id; |
3197 return frame; | 3468 return frame; |
3198 } | 3469 } |
3199 | 3470 |
| 3471 TranslatedFrame TranslatedFrame::BuiltinContinuationFrame( |
| 3472 BailoutId bailout_id, SharedFunctionInfo* shared_info, int height) { |
| 3473 TranslatedFrame frame(kBuiltinContinuation, shared_info->GetIsolate(), |
| 3474 shared_info, height); |
| 3475 frame.node_id_ = bailout_id; |
| 3476 return frame; |
| 3477 } |
3200 | 3478 |
3201 int TranslatedFrame::GetValueCount() { | 3479 int TranslatedFrame::GetValueCount() { |
3202 switch (kind()) { | 3480 switch (kind()) { |
3203 case kFunction: { | 3481 case kFunction: { |
3204 int parameter_count = | 3482 int parameter_count = |
3205 raw_shared_info_->internal_formal_parameter_count() + 1; | 3483 raw_shared_info_->internal_formal_parameter_count() + 1; |
3206 // + 1 for function. | 3484 // + 1 for function. |
3207 return height_ + parameter_count + 1; | 3485 return height_ + parameter_count + 1; |
3208 } | 3486 } |
3209 | 3487 |
3210 case kInterpretedFunction: { | 3488 case kInterpretedFunction: { |
3211 int parameter_count = | 3489 int parameter_count = |
3212 raw_shared_info_->internal_formal_parameter_count() + 1; | 3490 raw_shared_info_->internal_formal_parameter_count() + 1; |
3213 // + 2 for function and context. | 3491 // + 2 for function and context. |
3214 return height_ + parameter_count + 2; | 3492 return height_ + parameter_count + 2; |
3215 } | 3493 } |
3216 | 3494 |
3217 case kGetter: | 3495 case kGetter: |
3218 return 2; // Function and receiver. | 3496 return 2; // Function and receiver. |
3219 | 3497 |
3220 case kSetter: | 3498 case kSetter: |
3221 return 3; // Function, receiver and the value to set. | 3499 return 3; // Function, receiver and the value to set. |
3222 | 3500 |
3223 case kArgumentsAdaptor: | 3501 case kArgumentsAdaptor: |
3224 case kConstructStub: | 3502 case kConstructStub: |
| 3503 case kBuiltinContinuation: |
3225 return 1 + height_; | 3504 return 1 + height_; |
3226 | 3505 |
3227 case kTailCallerFunction: | 3506 case kTailCallerFunction: |
3228 return 1; // Function. | 3507 return 1; // Function. |
3229 | 3508 |
3230 case kCompiledStub: | 3509 case kCompiledStub: |
3231 return height_; | 3510 return height_; |
3232 | 3511 |
3233 case kInvalid: | 3512 case kInvalid: |
3234 UNREACHABLE(); | 3513 UNREACHABLE(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3319 if (trace_file != nullptr) { | 3598 if (trace_file != nullptr) { |
3320 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3599 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3321 PrintF(trace_file, " reading construct stub frame %s", name.get()); | 3600 PrintF(trace_file, " reading construct stub frame %s", name.get()); |
3322 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", | 3601 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
3323 bailout_id.ToInt(), height); | 3602 bailout_id.ToInt(), height); |
3324 } | 3603 } |
3325 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, | 3604 return TranslatedFrame::ConstructStubFrame(bailout_id, shared_info, |
3326 height); | 3605 height); |
3327 } | 3606 } |
3328 | 3607 |
| 3608 case Translation::BUILTIN_CONTINUATION_FRAME: { |
| 3609 BailoutId bailout_id = BailoutId(iterator->Next()); |
| 3610 SharedFunctionInfo* shared_info = |
| 3611 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3612 int height = iterator->Next(); |
| 3613 if (trace_file != nullptr) { |
| 3614 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
| 3615 PrintF(trace_file, " reading builtin continuation frame %s", |
| 3616 name.get()); |
| 3617 PrintF(trace_file, " => bailout_id=%d, height=%d; inputs:\n", |
| 3618 bailout_id.ToInt(), height); |
| 3619 } |
| 3620 return TranslatedFrame::BuiltinContinuationFrame(bailout_id, shared_info, |
| 3621 height); |
| 3622 } |
| 3623 |
3329 case Translation::GETTER_STUB_FRAME: { | 3624 case Translation::GETTER_STUB_FRAME: { |
3330 SharedFunctionInfo* shared_info = | 3625 SharedFunctionInfo* shared_info = |
3331 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 3626 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
3332 if (trace_file != nullptr) { | 3627 if (trace_file != nullptr) { |
3333 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); | 3628 std::unique_ptr<char[]> name = shared_info->DebugName()->ToCString(); |
3334 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); | 3629 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); |
3335 } | 3630 } |
3336 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, | 3631 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, |
3337 shared_info); | 3632 shared_info); |
3338 } | 3633 } |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3487 switch (opcode) { | 3782 switch (opcode) { |
3488 case Translation::BEGIN: | 3783 case Translation::BEGIN: |
3489 case Translation::JS_FRAME: | 3784 case Translation::JS_FRAME: |
3490 case Translation::INTERPRETED_FRAME: | 3785 case Translation::INTERPRETED_FRAME: |
3491 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3786 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
3492 case Translation::TAIL_CALLER_FRAME: | 3787 case Translation::TAIL_CALLER_FRAME: |
3493 case Translation::CONSTRUCT_STUB_FRAME: | 3788 case Translation::CONSTRUCT_STUB_FRAME: |
3494 case Translation::GETTER_STUB_FRAME: | 3789 case Translation::GETTER_STUB_FRAME: |
3495 case Translation::SETTER_STUB_FRAME: | 3790 case Translation::SETTER_STUB_FRAME: |
3496 case Translation::COMPILED_STUB_FRAME: | 3791 case Translation::COMPILED_STUB_FRAME: |
| 3792 case Translation::BUILTIN_CONTINUATION_FRAME: |
3497 // Peeled off before getting here. | 3793 // Peeled off before getting here. |
3498 break; | 3794 break; |
3499 | 3795 |
3500 case Translation::DUPLICATED_OBJECT: { | 3796 case Translation::DUPLICATED_OBJECT: { |
3501 int object_id = iterator->Next(); | 3797 int object_id = iterator->Next(); |
3502 if (trace_file != nullptr) { | 3798 if (trace_file != nullptr) { |
3503 PrintF(trace_file, "duplicated object #%d", object_id); | 3799 PrintF(trace_file, "duplicated object #%d", object_id); |
3504 } | 3800 } |
3505 object_positions_.push_back(object_positions_[object_id]); | 3801 object_positions_.push_back(object_positions_[object_id]); |
3506 TranslatedValue translated_value = | 3802 TranslatedValue translated_value = |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4467 CHECK(value_info->IsMaterializedObject()); | 4763 CHECK(value_info->IsMaterializedObject()); |
4468 | 4764 |
4469 value_info->value_ = | 4765 value_info->value_ = |
4470 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4766 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4471 } | 4767 } |
4472 } | 4768 } |
4473 } | 4769 } |
4474 | 4770 |
4475 } // namespace internal | 4771 } // namespace internal |
4476 } // namespace v8 | 4772 } // namespace v8 |
OLD | NEW |