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/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 | 504 |
505 Code* Deoptimizer::FindOptimizedCode(JSFunction* function) { | 505 Code* Deoptimizer::FindOptimizedCode(JSFunction* function) { |
506 Code* compiled_code = FindDeoptimizingCode(from_); | 506 Code* compiled_code = FindDeoptimizingCode(from_); |
507 return (compiled_code == NULL) | 507 return (compiled_code == NULL) |
508 ? static_cast<Code*>(isolate_->FindCodeObject(from_)) | 508 ? static_cast<Code*>(isolate_->FindCodeObject(from_)) |
509 : compiled_code; | 509 : compiled_code; |
510 } | 510 } |
511 | 511 |
512 | 512 |
513 void Deoptimizer::PrintFunctionName() { | 513 void Deoptimizer::PrintFunctionName() { |
514 if (function_ != nullptr && function_->IsJSFunction()) { | 514 if (function_->IsHeapObject() && function_->IsJSFunction()) { |
515 function_->ShortPrint(trace_scope_->file()); | 515 function_->ShortPrint(trace_scope_->file()); |
516 } else { | 516 } else { |
517 PrintF(trace_scope_->file(), | 517 PrintF(trace_scope_->file(), |
518 "%s", Code::Kind2String(compiled_code_->kind())); | 518 "%s", Code::Kind2String(compiled_code_->kind())); |
519 } | 519 } |
520 } | 520 } |
521 | 521 |
522 | 522 |
523 Deoptimizer::~Deoptimizer() { | 523 Deoptimizer::~Deoptimizer() { |
524 DCHECK(input_ == NULL && output_ == NULL); | 524 DCHECK(input_ == NULL && output_ == NULL); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 | 701 |
702 BailoutId node_id = input_data->AstId(bailout_id_); | 702 BailoutId node_id = input_data->AstId(bailout_id_); |
703 ByteArray* translations = input_data->TranslationByteArray(); | 703 ByteArray* translations = input_data->TranslationByteArray(); |
704 unsigned translation_index = | 704 unsigned translation_index = |
705 input_data->TranslationIndex(bailout_id_)->value(); | 705 input_data->TranslationIndex(bailout_id_)->value(); |
706 | 706 |
707 TranslationIterator state_iterator(translations, translation_index); | 707 TranslationIterator state_iterator(translations, translation_index); |
708 translated_state_.Init( | 708 translated_state_.Init( |
709 input_->GetFramePointerAddress(), &state_iterator, | 709 input_->GetFramePointerAddress(), &state_iterator, |
710 input_data->LiteralArray(), input_->GetRegisterValues(), | 710 input_data->LiteralArray(), input_->GetRegisterValues(), |
711 trace_scope_ == nullptr ? nullptr : trace_scope_->file()); | 711 trace_scope_ == nullptr ? nullptr : trace_scope_->file(), |
| 712 function_->IsHeapObject() |
| 713 ? function_->shared()->internal_formal_parameter_count() |
| 714 : 0); |
712 | 715 |
713 // Do the input frame to output frame(s) translation. | 716 // Do the input frame to output frame(s) translation. |
714 size_t count = translated_state_.frames().size(); | 717 size_t count = translated_state_.frames().size(); |
715 // If we are supposed to go to the catch handler, find the catching frame | 718 // If we are supposed to go to the catch handler, find the catching frame |
716 // for the catch and make sure we only deoptimize upto that frame. | 719 // for the catch and make sure we only deoptimize upto that frame. |
717 if (deoptimizing_throw_) { | 720 if (deoptimizing_throw_) { |
718 size_t catch_handler_frame_index = count; | 721 size_t catch_handler_frame_index = count; |
719 for (size_t i = count; i-- > 0;) { | 722 for (size_t i = count; i-- > 0;) { |
720 catch_handler_pc_offset_ = LookupCatchHandler( | 723 catch_handler_pc_offset_ = LookupCatchHandler( |
721 &(translated_state_.frames()[i]), &catch_handler_data_); | 724 &(translated_state_.frames()[i]), &catch_handler_data_); |
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2392 buffer_->Add(COMPILED_STUB_FRAME); | 2395 buffer_->Add(COMPILED_STUB_FRAME); |
2393 buffer_->Add(height); | 2396 buffer_->Add(height); |
2394 } | 2397 } |
2395 | 2398 |
2396 | 2399 |
2397 void Translation::BeginArgumentsObject(int args_length) { | 2400 void Translation::BeginArgumentsObject(int args_length) { |
2398 buffer_->Add(ARGUMENTS_OBJECT); | 2401 buffer_->Add(ARGUMENTS_OBJECT); |
2399 buffer_->Add(args_length); | 2402 buffer_->Add(args_length); |
2400 } | 2403 } |
2401 | 2404 |
| 2405 void Translation::ArgumentsElements(bool is_rest) { |
| 2406 buffer_->Add(ARGUMENTS_ELEMENTS); |
| 2407 buffer_->Add(is_rest); |
| 2408 } |
2402 | 2409 |
2403 void Translation::BeginCapturedObject(int length) { | 2410 void Translation::BeginCapturedObject(int length) { |
2404 buffer_->Add(CAPTURED_OBJECT); | 2411 buffer_->Add(CAPTURED_OBJECT); |
2405 buffer_->Add(length); | 2412 buffer_->Add(length); |
2406 } | 2413 } |
2407 | 2414 |
2408 | 2415 |
2409 void Translation::DuplicateObject(int object_index) { | 2416 void Translation::DuplicateObject(int object_index) { |
2410 buffer_->Add(DUPLICATED_OBJECT); | 2417 buffer_->Add(DUPLICATED_OBJECT); |
2411 buffer_->Add(object_index); | 2418 buffer_->Add(object_index); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2525 case COMPILED_STUB_FRAME: | 2532 case COMPILED_STUB_FRAME: |
2526 case TAIL_CALLER_FRAME: | 2533 case TAIL_CALLER_FRAME: |
2527 return 1; | 2534 return 1; |
2528 case BEGIN: | 2535 case BEGIN: |
2529 case ARGUMENTS_ADAPTOR_FRAME: | 2536 case ARGUMENTS_ADAPTOR_FRAME: |
2530 return 2; | 2537 return 2; |
2531 case JS_FRAME: | 2538 case JS_FRAME: |
2532 case INTERPRETED_FRAME: | 2539 case INTERPRETED_FRAME: |
2533 case CONSTRUCT_STUB_FRAME: | 2540 case CONSTRUCT_STUB_FRAME: |
2534 return 3; | 2541 return 3; |
| 2542 case ARGUMENTS_ELEMENTS: |
| 2543 return 1; |
2535 } | 2544 } |
2536 FATAL("Unexpected translation type"); | 2545 FATAL("Unexpected translation type"); |
2537 return -1; | 2546 return -1; |
2538 } | 2547 } |
2539 | 2548 |
2540 | 2549 |
2541 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 2550 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
2542 | 2551 |
2543 const char* Translation::StringFor(Opcode opcode) { | 2552 const char* Translation::StringFor(Opcode opcode) { |
2544 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; | 2553 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2783 | 2792 |
2784 // static | 2793 // static |
2785 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, | 2794 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, |
2786 int length, | 2795 int length, |
2787 int object_index) { | 2796 int object_index) { |
2788 TranslatedValue slot(container, kArgumentsObject); | 2797 TranslatedValue slot(container, kArgumentsObject); |
2789 slot.materialization_info_ = {object_index, length}; | 2798 slot.materialization_info_ = {object_index, length}; |
2790 return slot; | 2799 return slot; |
2791 } | 2800 } |
2792 | 2801 |
2793 | |
2794 // static | 2802 // static |
2795 TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container, | 2803 TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container, |
2796 int length, | 2804 int length, |
2797 int object_index) { | 2805 int object_index) { |
2798 TranslatedValue slot(container, kCapturedObject); | 2806 TranslatedValue slot(container, kCapturedObject); |
2799 slot.materialization_info_ = {object_index, length}; | 2807 slot.materialization_info_ = {object_index, length}; |
2800 return slot; | 2808 return slot; |
2801 } | 2809 } |
2802 | 2810 |
2803 | 2811 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3293 PrintF(trace_file, | 3301 PrintF(trace_file, |
3294 " reading compiler stub frame => height=%d; inputs:\n", height); | 3302 " reading compiler stub frame => height=%d; inputs:\n", height); |
3295 } | 3303 } |
3296 return TranslatedFrame::CompiledStubFrame(height, | 3304 return TranslatedFrame::CompiledStubFrame(height, |
3297 literal_array->GetIsolate()); | 3305 literal_array->GetIsolate()); |
3298 } | 3306 } |
3299 | 3307 |
3300 case Translation::BEGIN: | 3308 case Translation::BEGIN: |
3301 case Translation::DUPLICATED_OBJECT: | 3309 case Translation::DUPLICATED_OBJECT: |
3302 case Translation::ARGUMENTS_OBJECT: | 3310 case Translation::ARGUMENTS_OBJECT: |
| 3311 case Translation::ARGUMENTS_ELEMENTS: |
3303 case Translation::CAPTURED_OBJECT: | 3312 case Translation::CAPTURED_OBJECT: |
3304 case Translation::REGISTER: | 3313 case Translation::REGISTER: |
3305 case Translation::INT32_REGISTER: | 3314 case Translation::INT32_REGISTER: |
3306 case Translation::UINT32_REGISTER: | 3315 case Translation::UINT32_REGISTER: |
3307 case Translation::BOOL_REGISTER: | 3316 case Translation::BOOL_REGISTER: |
3308 case Translation::FLOAT_REGISTER: | 3317 case Translation::FLOAT_REGISTER: |
3309 case Translation::DOUBLE_REGISTER: | 3318 case Translation::DOUBLE_REGISTER: |
3310 case Translation::STACK_SLOT: | 3319 case Translation::STACK_SLOT: |
3311 case Translation::INT32_STACK_SLOT: | 3320 case Translation::INT32_STACK_SLOT: |
3312 case Translation::UINT32_STACK_SLOT: | 3321 case Translation::UINT32_STACK_SLOT: |
(...skipping 15 matching lines...) Expand all Loading... |
3328 while (values_to_skip > 0) { | 3337 while (values_to_skip > 0) { |
3329 // Consume the current element. | 3338 // Consume the current element. |
3330 values_to_skip--; | 3339 values_to_skip--; |
3331 // Add all the children. | 3340 // Add all the children. |
3332 values_to_skip += (*iter)->GetChildrenCount(); | 3341 values_to_skip += (*iter)->GetChildrenCount(); |
3333 | 3342 |
3334 (*iter)++; | 3343 (*iter)++; |
3335 } | 3344 } |
3336 } | 3345 } |
3337 | 3346 |
| 3347 // Creates translated values for an arguments backing store, or the backing |
| 3348 // store for the rest parameters if {is_rest} is true. The TranslatedValue |
| 3349 // objects for the fields are not read from the TranslationIterator, but instead |
| 3350 // created on-the-fly based on dynamic information in the optimized frame. |
| 3351 void TranslatedState::CreateArgumentsElementsTranslatedValues( |
| 3352 int frame_index, Address input_frame_pointer, bool is_rest) { |
| 3353 TranslatedFrame& frame = frames_[frame_index]; |
3338 | 3354 |
3339 // We can't intermix stack decoding and allocations because | 3355 Address parent_frame_pointer = *reinterpret_cast<Address*>( |
3340 // deoptimization infrastracture is not GC safe. | 3356 input_frame_pointer + StandardFrameConstants::kCallerFPOffset); |
| 3357 intptr_t parent_frame_type = Memory::intptr_at( |
| 3358 parent_frame_pointer + CommonFrameConstants::kContextOrFrameTypeOffset); |
| 3359 int length; |
| 3360 Address arguments_frame; |
| 3361 if (parent_frame_type == |
| 3362 StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)) { |
| 3363 length = Smi::cast(*reinterpret_cast<Object**>( |
| 3364 parent_frame_pointer + |
| 3365 ArgumentsAdaptorFrameConstants::kLengthOffset)) |
| 3366 ->value(); |
| 3367 arguments_frame = parent_frame_pointer; |
| 3368 } else { |
| 3369 length = formal_parameter_count_; |
| 3370 arguments_frame = input_frame_pointer; |
| 3371 } |
| 3372 |
| 3373 if (is_rest) { |
| 3374 // If the actual number of arguments is less than the number of formal |
| 3375 // parameters, we have zero rest parameters. |
| 3376 length = std::max(0, length - formal_parameter_count_); |
| 3377 } |
| 3378 |
| 3379 int object_index = static_cast<int>(object_positions_.size()); |
| 3380 int value_index = static_cast<int>(frame.values_.size()); |
| 3381 object_positions_.push_back({frame_index, value_index}); |
| 3382 frame.Add(TranslatedValue::NewDeferredObject( |
| 3383 this, length + FixedArray::kHeaderSize / kPointerSize, object_index)); |
| 3384 |
| 3385 frame.Add( |
| 3386 TranslatedValue::NewTagged(this, isolate_->heap()->fixed_array_map())); |
| 3387 frame.Add(TranslatedValue::NewInt32(this, length)); |
| 3388 |
| 3389 for (int i = length - 1; i >= 0; --i) { |
| 3390 Address argument_slot = arguments_frame + |
| 3391 CommonFrameConstants::kFixedFrameSizeAboveFp + |
| 3392 i * kPointerSize; |
| 3393 frame.Add(TranslatedValue::NewTagged( |
| 3394 this, *reinterpret_cast<Object**>(argument_slot))); |
| 3395 } |
| 3396 } |
| 3397 |
| 3398 // We can't intermix stack decoding and allocations because the deoptimization |
| 3399 // infrastracture is not GC safe. |
3341 // Thus we build a temporary structure in malloced space. | 3400 // Thus we build a temporary structure in malloced space. |
3342 TranslatedValue TranslatedState::CreateNextTranslatedValue( | 3401 // The TranslatedValue objects created correspond to the static translation |
3343 int frame_index, int value_index, TranslationIterator* iterator, | 3402 // instructions from the TranslationIterator, except for |
3344 FixedArray* literal_array, Address fp, RegisterValues* registers, | 3403 // Translation::ARGUMENTS_ELEMENTS, where the number and values of the |
3345 FILE* trace_file) { | 3404 // FixedArray elements depend on dynamic information from the optimized frame. |
| 3405 // Returns the number of expected nested translations from the |
| 3406 // TranslationIterator. |
| 3407 int TranslatedState::CreateNextTranslatedValue( |
| 3408 int frame_index, TranslationIterator* iterator, FixedArray* literal_array, |
| 3409 Address fp, RegisterValues* registers, FILE* trace_file) { |
3346 disasm::NameConverter converter; | 3410 disasm::NameConverter converter; |
3347 | 3411 |
| 3412 TranslatedFrame& frame = frames_[frame_index]; |
| 3413 int value_index = static_cast<int>(frame.values_.size()); |
| 3414 |
3348 Translation::Opcode opcode = | 3415 Translation::Opcode opcode = |
3349 static_cast<Translation::Opcode>(iterator->Next()); | 3416 static_cast<Translation::Opcode>(iterator->Next()); |
3350 switch (opcode) { | 3417 switch (opcode) { |
3351 case Translation::BEGIN: | 3418 case Translation::BEGIN: |
3352 case Translation::JS_FRAME: | 3419 case Translation::JS_FRAME: |
3353 case Translation::INTERPRETED_FRAME: | 3420 case Translation::INTERPRETED_FRAME: |
3354 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3421 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
3355 case Translation::TAIL_CALLER_FRAME: | 3422 case Translation::TAIL_CALLER_FRAME: |
3356 case Translation::CONSTRUCT_STUB_FRAME: | 3423 case Translation::CONSTRUCT_STUB_FRAME: |
3357 case Translation::GETTER_STUB_FRAME: | 3424 case Translation::GETTER_STUB_FRAME: |
3358 case Translation::SETTER_STUB_FRAME: | 3425 case Translation::SETTER_STUB_FRAME: |
3359 case Translation::COMPILED_STUB_FRAME: | 3426 case Translation::COMPILED_STUB_FRAME: |
3360 // Peeled off before getting here. | 3427 // Peeled off before getting here. |
3361 break; | 3428 break; |
3362 | 3429 |
3363 case Translation::DUPLICATED_OBJECT: { | 3430 case Translation::DUPLICATED_OBJECT: { |
3364 int object_id = iterator->Next(); | 3431 int object_id = iterator->Next(); |
3365 if (trace_file != nullptr) { | 3432 if (trace_file != nullptr) { |
3366 PrintF(trace_file, "duplicated object #%d", object_id); | 3433 PrintF(trace_file, "duplicated object #%d", object_id); |
3367 } | 3434 } |
3368 object_positions_.push_back(object_positions_[object_id]); | 3435 object_positions_.push_back(object_positions_[object_id]); |
3369 return TranslatedValue::NewDuplicateObject(this, object_id); | 3436 TranslatedValue translated_value = |
| 3437 TranslatedValue::NewDuplicateObject(this, object_id); |
| 3438 frame.Add(translated_value); |
| 3439 return translated_value.GetChildrenCount(); |
3370 } | 3440 } |
3371 | 3441 |
3372 case Translation::ARGUMENTS_OBJECT: { | 3442 case Translation::ARGUMENTS_OBJECT: { |
3373 int arg_count = iterator->Next(); | 3443 int arg_count = iterator->Next(); |
3374 int object_index = static_cast<int>(object_positions_.size()); | 3444 int object_index = static_cast<int>(object_positions_.size()); |
3375 if (trace_file != nullptr) { | 3445 if (trace_file != nullptr) { |
3376 PrintF(trace_file, "argumets object #%d (length = %d)", object_index, | 3446 PrintF(trace_file, "arguments object #%d (length = %d)", object_index, |
3377 arg_count); | 3447 arg_count); |
3378 } | 3448 } |
3379 object_positions_.push_back({frame_index, value_index}); | 3449 object_positions_.push_back({frame_index, value_index}); |
3380 return TranslatedValue::NewArgumentsObject(this, arg_count, object_index); | 3450 TranslatedValue translated_value = |
| 3451 TranslatedValue::NewArgumentsObject(this, arg_count, object_index); |
| 3452 frame.Add(translated_value); |
| 3453 return translated_value.GetChildrenCount(); |
| 3454 } |
| 3455 |
| 3456 case Translation::ARGUMENTS_ELEMENTS: { |
| 3457 bool is_rest = iterator->Next(); |
| 3458 CreateArgumentsElementsTranslatedValues(frame_index, fp, is_rest); |
| 3459 return 0; |
3381 } | 3460 } |
3382 | 3461 |
3383 case Translation::CAPTURED_OBJECT: { | 3462 case Translation::CAPTURED_OBJECT: { |
3384 int field_count = iterator->Next(); | 3463 int field_count = iterator->Next(); |
3385 int object_index = static_cast<int>(object_positions_.size()); | 3464 int object_index = static_cast<int>(object_positions_.size()); |
3386 if (trace_file != nullptr) { | 3465 if (trace_file != nullptr) { |
3387 PrintF(trace_file, "captured object #%d (length = %d)", object_index, | 3466 PrintF(trace_file, "captured object #%d (length = %d)", object_index, |
3388 field_count); | 3467 field_count); |
3389 } | 3468 } |
3390 object_positions_.push_back({frame_index, value_index}); | 3469 object_positions_.push_back({frame_index, value_index}); |
3391 return TranslatedValue::NewDeferredObject(this, field_count, | 3470 TranslatedValue translated_value = |
3392 object_index); | 3471 TranslatedValue::NewDeferredObject(this, field_count, object_index); |
| 3472 frame.Add(translated_value); |
| 3473 return translated_value.GetChildrenCount(); |
3393 } | 3474 } |
3394 | 3475 |
3395 case Translation::REGISTER: { | 3476 case Translation::REGISTER: { |
3396 int input_reg = iterator->Next(); | 3477 int input_reg = iterator->Next(); |
3397 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3478 if (registers == nullptr) { |
| 3479 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3480 frame.Add(translated_value); |
| 3481 return translated_value.GetChildrenCount(); |
| 3482 } |
3398 intptr_t value = registers->GetRegister(input_reg); | 3483 intptr_t value = registers->GetRegister(input_reg); |
3399 if (trace_file != nullptr) { | 3484 if (trace_file != nullptr) { |
3400 PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value, | 3485 PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value, |
3401 converter.NameOfCPURegister(input_reg)); | 3486 converter.NameOfCPURegister(input_reg)); |
3402 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3487 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
3403 } | 3488 } |
3404 return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | 3489 TranslatedValue translated_value = |
| 3490 TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); |
| 3491 frame.Add(translated_value); |
| 3492 return translated_value.GetChildrenCount(); |
3405 } | 3493 } |
3406 | 3494 |
3407 case Translation::INT32_REGISTER: { | 3495 case Translation::INT32_REGISTER: { |
3408 int input_reg = iterator->Next(); | 3496 int input_reg = iterator->Next(); |
3409 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3497 if (registers == nullptr) { |
| 3498 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3499 frame.Add(translated_value); |
| 3500 return translated_value.GetChildrenCount(); |
| 3501 } |
3410 intptr_t value = registers->GetRegister(input_reg); | 3502 intptr_t value = registers->GetRegister(input_reg); |
3411 if (trace_file != nullptr) { | 3503 if (trace_file != nullptr) { |
3412 PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value, | 3504 PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value, |
3413 converter.NameOfCPURegister(input_reg)); | 3505 converter.NameOfCPURegister(input_reg)); |
3414 } | 3506 } |
3415 return TranslatedValue::NewInt32(this, static_cast<int32_t>(value)); | 3507 TranslatedValue translated_value = |
| 3508 TranslatedValue::NewInt32(this, static_cast<int32_t>(value)); |
| 3509 frame.Add(translated_value); |
| 3510 return translated_value.GetChildrenCount(); |
3416 } | 3511 } |
3417 | 3512 |
3418 case Translation::UINT32_REGISTER: { | 3513 case Translation::UINT32_REGISTER: { |
3419 int input_reg = iterator->Next(); | 3514 int input_reg = iterator->Next(); |
3420 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3515 if (registers == nullptr) { |
| 3516 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3517 frame.Add(translated_value); |
| 3518 return translated_value.GetChildrenCount(); |
| 3519 } |
3421 intptr_t value = registers->GetRegister(input_reg); | 3520 intptr_t value = registers->GetRegister(input_reg); |
3422 if (trace_file != nullptr) { | 3521 if (trace_file != nullptr) { |
3423 PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value, | 3522 PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value, |
3424 converter.NameOfCPURegister(input_reg)); | 3523 converter.NameOfCPURegister(input_reg)); |
3425 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3524 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
3426 } | 3525 } |
3427 return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value)); | 3526 TranslatedValue translated_value = |
| 3527 TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value)); |
| 3528 frame.Add(translated_value); |
| 3529 return translated_value.GetChildrenCount(); |
3428 } | 3530 } |
3429 | 3531 |
3430 case Translation::BOOL_REGISTER: { | 3532 case Translation::BOOL_REGISTER: { |
3431 int input_reg = iterator->Next(); | 3533 int input_reg = iterator->Next(); |
3432 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3534 if (registers == nullptr) { |
| 3535 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3536 frame.Add(translated_value); |
| 3537 return translated_value.GetChildrenCount(); |
| 3538 } |
3433 intptr_t value = registers->GetRegister(input_reg); | 3539 intptr_t value = registers->GetRegister(input_reg); |
3434 if (trace_file != nullptr) { | 3540 if (trace_file != nullptr) { |
3435 PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value, | 3541 PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value, |
3436 converter.NameOfCPURegister(input_reg)); | 3542 converter.NameOfCPURegister(input_reg)); |
3437 } | 3543 } |
3438 return TranslatedValue::NewBool(this, static_cast<uint32_t>(value)); | 3544 TranslatedValue translated_value = |
| 3545 TranslatedValue::NewBool(this, static_cast<uint32_t>(value)); |
| 3546 frame.Add(translated_value); |
| 3547 return translated_value.GetChildrenCount(); |
3439 } | 3548 } |
3440 | 3549 |
3441 case Translation::FLOAT_REGISTER: { | 3550 case Translation::FLOAT_REGISTER: { |
3442 int input_reg = iterator->Next(); | 3551 int input_reg = iterator->Next(); |
3443 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3552 if (registers == nullptr) { |
| 3553 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3554 frame.Add(translated_value); |
| 3555 return translated_value.GetChildrenCount(); |
| 3556 } |
3444 Float32 value = registers->GetFloatRegister(input_reg); | 3557 Float32 value = registers->GetFloatRegister(input_reg); |
3445 if (trace_file != nullptr) { | 3558 if (trace_file != nullptr) { |
3446 PrintF(trace_file, "%e ; %s (float)", value.get_scalar(), | 3559 PrintF(trace_file, "%e ; %s (float)", value.get_scalar(), |
3447 RegisterConfiguration::Crankshaft()->GetFloatRegisterName( | 3560 RegisterConfiguration::Crankshaft()->GetFloatRegisterName( |
3448 input_reg)); | 3561 input_reg)); |
3449 } | 3562 } |
3450 return TranslatedValue::NewFloat(this, value); | 3563 TranslatedValue translated_value = TranslatedValue::NewFloat(this, value); |
| 3564 frame.Add(translated_value); |
| 3565 return translated_value.GetChildrenCount(); |
3451 } | 3566 } |
3452 | 3567 |
3453 case Translation::DOUBLE_REGISTER: { | 3568 case Translation::DOUBLE_REGISTER: { |
3454 int input_reg = iterator->Next(); | 3569 int input_reg = iterator->Next(); |
3455 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3570 if (registers == nullptr) { |
| 3571 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); |
| 3572 frame.Add(translated_value); |
| 3573 return translated_value.GetChildrenCount(); |
| 3574 } |
3456 Float64 value = registers->GetDoubleRegister(input_reg); | 3575 Float64 value = registers->GetDoubleRegister(input_reg); |
3457 if (trace_file != nullptr) { | 3576 if (trace_file != nullptr) { |
3458 PrintF(trace_file, "%e ; %s (double)", value.get_scalar(), | 3577 PrintF(trace_file, "%e ; %s (double)", value.get_scalar(), |
3459 RegisterConfiguration::Crankshaft()->GetDoubleRegisterName( | 3578 RegisterConfiguration::Crankshaft()->GetDoubleRegisterName( |
3460 input_reg)); | 3579 input_reg)); |
3461 } | 3580 } |
3462 return TranslatedValue::NewDouble(this, value); | 3581 TranslatedValue translated_value = |
| 3582 TranslatedValue::NewDouble(this, value); |
| 3583 frame.Add(translated_value); |
| 3584 return translated_value.GetChildrenCount(); |
3463 } | 3585 } |
3464 | 3586 |
3465 case Translation::STACK_SLOT: { | 3587 case Translation::STACK_SLOT: { |
3466 int slot_offset = | 3588 int slot_offset = |
3467 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3589 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3468 intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset)); | 3590 intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset)); |
3469 if (trace_file != nullptr) { | 3591 if (trace_file != nullptr) { |
3470 PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value, | 3592 PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value, |
3471 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3593 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
3472 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3594 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
3473 } | 3595 } |
3474 return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | 3596 TranslatedValue translated_value = |
| 3597 TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); |
| 3598 frame.Add(translated_value); |
| 3599 return translated_value.GetChildrenCount(); |
3475 } | 3600 } |
3476 | 3601 |
3477 case Translation::INT32_STACK_SLOT: { | 3602 case Translation::INT32_STACK_SLOT: { |
3478 int slot_offset = | 3603 int slot_offset = |
3479 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3604 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3480 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3605 uint32_t value = GetUInt32Slot(fp, slot_offset); |
3481 if (trace_file != nullptr) { | 3606 if (trace_file != nullptr) { |
3482 PrintF(trace_file, "%d ; (int) [fp %c %d] ", | 3607 PrintF(trace_file, "%d ; (int) [fp %c %d] ", |
3483 static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+', | 3608 static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+', |
3484 std::abs(slot_offset)); | 3609 std::abs(slot_offset)); |
3485 } | 3610 } |
3486 return TranslatedValue::NewInt32(this, value); | 3611 TranslatedValue translated_value = TranslatedValue::NewInt32(this, value); |
| 3612 frame.Add(translated_value); |
| 3613 return translated_value.GetChildrenCount(); |
3487 } | 3614 } |
3488 | 3615 |
3489 case Translation::UINT32_STACK_SLOT: { | 3616 case Translation::UINT32_STACK_SLOT: { |
3490 int slot_offset = | 3617 int slot_offset = |
3491 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3618 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3492 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3619 uint32_t value = GetUInt32Slot(fp, slot_offset); |
3493 if (trace_file != nullptr) { | 3620 if (trace_file != nullptr) { |
3494 PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value, | 3621 PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value, |
3495 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3622 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
3496 } | 3623 } |
3497 return TranslatedValue::NewUInt32(this, value); | 3624 TranslatedValue translated_value = |
| 3625 TranslatedValue::NewUInt32(this, value); |
| 3626 frame.Add(translated_value); |
| 3627 return translated_value.GetChildrenCount(); |
3498 } | 3628 } |
3499 | 3629 |
3500 case Translation::BOOL_STACK_SLOT: { | 3630 case Translation::BOOL_STACK_SLOT: { |
3501 int slot_offset = | 3631 int slot_offset = |
3502 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3632 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3503 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3633 uint32_t value = GetUInt32Slot(fp, slot_offset); |
3504 if (trace_file != nullptr) { | 3634 if (trace_file != nullptr) { |
3505 PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value, | 3635 PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value, |
3506 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3636 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
3507 } | 3637 } |
3508 return TranslatedValue::NewBool(this, value); | 3638 TranslatedValue translated_value = TranslatedValue::NewBool(this, value); |
| 3639 frame.Add(translated_value); |
| 3640 return translated_value.GetChildrenCount(); |
3509 } | 3641 } |
3510 | 3642 |
3511 case Translation::FLOAT_STACK_SLOT: { | 3643 case Translation::FLOAT_STACK_SLOT: { |
3512 int slot_offset = | 3644 int slot_offset = |
3513 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3645 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3514 Float32 value = GetFloatSlot(fp, slot_offset); | 3646 Float32 value = GetFloatSlot(fp, slot_offset); |
3515 if (trace_file != nullptr) { | 3647 if (trace_file != nullptr) { |
3516 PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(), | 3648 PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(), |
3517 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3649 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
3518 } | 3650 } |
3519 return TranslatedValue::NewFloat(this, value); | 3651 TranslatedValue translated_value = TranslatedValue::NewFloat(this, value); |
| 3652 frame.Add(translated_value); |
| 3653 return translated_value.GetChildrenCount(); |
3520 } | 3654 } |
3521 | 3655 |
3522 case Translation::DOUBLE_STACK_SLOT: { | 3656 case Translation::DOUBLE_STACK_SLOT: { |
3523 int slot_offset = | 3657 int slot_offset = |
3524 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3658 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
3525 Float64 value = GetDoubleSlot(fp, slot_offset); | 3659 Float64 value = GetDoubleSlot(fp, slot_offset); |
3526 if (trace_file != nullptr) { | 3660 if (trace_file != nullptr) { |
3527 PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(), | 3661 PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(), |
3528 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3662 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
3529 } | 3663 } |
3530 return TranslatedValue::NewDouble(this, value); | 3664 TranslatedValue translated_value = |
| 3665 TranslatedValue::NewDouble(this, value); |
| 3666 frame.Add(translated_value); |
| 3667 return translated_value.GetChildrenCount(); |
3531 } | 3668 } |
3532 | 3669 |
3533 case Translation::LITERAL: { | 3670 case Translation::LITERAL: { |
3534 int literal_index = iterator->Next(); | 3671 int literal_index = iterator->Next(); |
3535 Object* value = literal_array->get(literal_index); | 3672 Object* value = literal_array->get(literal_index); |
3536 if (trace_file != nullptr) { | 3673 if (trace_file != nullptr) { |
3537 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", | 3674 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", |
3538 reinterpret_cast<intptr_t>(value), literal_index); | 3675 reinterpret_cast<intptr_t>(value), literal_index); |
3539 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3676 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
3540 } | 3677 } |
3541 | 3678 |
3542 return TranslatedValue::NewTagged(this, value); | 3679 TranslatedValue translated_value = |
| 3680 TranslatedValue::NewTagged(this, value); |
| 3681 frame.Add(translated_value); |
| 3682 return translated_value.GetChildrenCount(); |
3543 } | 3683 } |
3544 } | 3684 } |
3545 | 3685 |
3546 FATAL("We should never get here - unexpected deopt info."); | 3686 FATAL("We should never get here - unexpected deopt info."); |
3547 return TranslatedValue(nullptr, TranslatedValue::kInvalid); | 3687 TranslatedValue translated_value = |
| 3688 TranslatedValue(nullptr, TranslatedValue::kInvalid); |
| 3689 frame.Add(translated_value); |
| 3690 return translated_value.GetChildrenCount(); |
3548 } | 3691 } |
3549 | 3692 |
3550 | 3693 |
3551 TranslatedState::TranslatedState(JavaScriptFrame* frame) | 3694 TranslatedState::TranslatedState(JavaScriptFrame* frame) |
3552 : isolate_(nullptr), | 3695 : isolate_(nullptr), |
3553 stack_frame_pointer_(nullptr), | 3696 stack_frame_pointer_(nullptr), |
3554 has_adapted_arguments_(false) { | 3697 has_adapted_arguments_(false) { |
3555 int deopt_index = Safepoint::kNoDeoptimizationIndex; | 3698 int deopt_index = Safepoint::kNoDeoptimizationIndex; |
3556 DeoptimizationInputData* data = | 3699 DeoptimizationInputData* data = |
3557 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); | 3700 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
3558 DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex); | 3701 DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex); |
3559 TranslationIterator it(data->TranslationByteArray(), | 3702 TranslationIterator it(data->TranslationByteArray(), |
3560 data->TranslationIndex(deopt_index)->value()); | 3703 data->TranslationIndex(deopt_index)->value()); |
3561 Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */, | 3704 Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */, |
3562 nullptr /* trace file */); | 3705 nullptr /* trace file */, |
| 3706 frame->function()->shared()->internal_formal_parameter_count()); |
3563 } | 3707 } |
3564 | 3708 |
3565 | 3709 |
3566 TranslatedState::TranslatedState() | 3710 TranslatedState::TranslatedState() |
3567 : isolate_(nullptr), | 3711 : isolate_(nullptr), |
3568 stack_frame_pointer_(nullptr), | 3712 stack_frame_pointer_(nullptr), |
3569 has_adapted_arguments_(false) {} | 3713 has_adapted_arguments_(false) {} |
3570 | 3714 |
3571 | |
3572 void TranslatedState::Init(Address input_frame_pointer, | 3715 void TranslatedState::Init(Address input_frame_pointer, |
3573 TranslationIterator* iterator, | 3716 TranslationIterator* iterator, |
3574 FixedArray* literal_array, RegisterValues* registers, | 3717 FixedArray* literal_array, RegisterValues* registers, |
3575 FILE* trace_file) { | 3718 FILE* trace_file, int formal_parameter_count) { |
3576 DCHECK(frames_.empty()); | 3719 DCHECK(frames_.empty()); |
3577 | 3720 |
| 3721 formal_parameter_count_ = formal_parameter_count; |
| 3722 |
3578 isolate_ = literal_array->GetIsolate(); | 3723 isolate_ = literal_array->GetIsolate(); |
3579 // Read out the 'header' translation. | 3724 // Read out the 'header' translation. |
3580 Translation::Opcode opcode = | 3725 Translation::Opcode opcode = |
3581 static_cast<Translation::Opcode>(iterator->Next()); | 3726 static_cast<Translation::Opcode>(iterator->Next()); |
3582 CHECK(opcode == Translation::BEGIN); | 3727 CHECK(opcode == Translation::BEGIN); |
3583 | 3728 |
3584 int count = iterator->Next(); | 3729 int count = iterator->Next(); |
3585 iterator->Next(); // Drop JS frames count. | 3730 iterator->Next(); // Drop JS frames count. |
3586 | 3731 |
3587 frames_.reserve(count); | 3732 frames_.reserve(count); |
3588 | 3733 |
3589 std::stack<int> nested_counts; | 3734 std::stack<int> nested_counts; |
3590 | 3735 |
3591 // Read the frames | 3736 // Read the frames |
3592 for (int i = 0; i < count; i++) { | 3737 for (int frame_index = 0; frame_index < count; frame_index++) { |
3593 // Read the frame descriptor. | 3738 // Read the frame descriptor. |
3594 frames_.push_back(CreateNextTranslatedFrame( | 3739 frames_.push_back(CreateNextTranslatedFrame( |
3595 iterator, literal_array, input_frame_pointer, trace_file)); | 3740 iterator, literal_array, input_frame_pointer, trace_file)); |
3596 TranslatedFrame& frame = frames_.back(); | 3741 TranslatedFrame& frame = frames_.back(); |
3597 | 3742 |
3598 // Read the values. | 3743 // Read the values. |
3599 int values_to_process = frame.GetValueCount(); | 3744 int values_to_process = frame.GetValueCount(); |
3600 while (values_to_process > 0 || !nested_counts.empty()) { | 3745 while (values_to_process > 0 || !nested_counts.empty()) { |
3601 if (trace_file != nullptr) { | 3746 if (trace_file != nullptr) { |
3602 if (nested_counts.empty()) { | 3747 if (nested_counts.empty()) { |
3603 // For top level values, print the value number. | 3748 // For top level values, print the value number. |
3604 PrintF(trace_file, " %3i: ", | 3749 PrintF(trace_file, " %3i: ", |
3605 frame.GetValueCount() - values_to_process); | 3750 frame.GetValueCount() - values_to_process); |
3606 } else { | 3751 } else { |
3607 // Take care of indenting for nested values. | 3752 // Take care of indenting for nested values. |
3608 PrintF(trace_file, " "); | 3753 PrintF(trace_file, " "); |
3609 for (size_t j = 0; j < nested_counts.size(); j++) { | 3754 for (size_t j = 0; j < nested_counts.size(); j++) { |
3610 PrintF(trace_file, " "); | 3755 PrintF(trace_file, " "); |
3611 } | 3756 } |
3612 } | 3757 } |
3613 } | 3758 } |
3614 | 3759 |
3615 TranslatedValue value = CreateNextTranslatedValue( | 3760 int nested_count = |
3616 i, static_cast<int>(frame.values_.size()), iterator, literal_array, | 3761 CreateNextTranslatedValue(frame_index, iterator, literal_array, |
3617 input_frame_pointer, registers, trace_file); | 3762 input_frame_pointer, registers, trace_file); |
3618 frame.Add(value); | |
3619 | 3763 |
3620 if (trace_file != nullptr) { | 3764 if (trace_file != nullptr) { |
3621 PrintF(trace_file, "\n"); | 3765 PrintF(trace_file, "\n"); |
3622 } | 3766 } |
3623 | 3767 |
3624 // Update the value count and resolve the nesting. | 3768 // Update the value count and resolve the nesting. |
3625 values_to_process--; | 3769 values_to_process--; |
3626 int children_count = value.GetChildrenCount(); | 3770 if (nested_count > 0) { |
3627 if (children_count > 0) { | |
3628 nested_counts.push(values_to_process); | 3771 nested_counts.push(values_to_process); |
3629 values_to_process = children_count; | 3772 values_to_process = nested_count; |
3630 } else { | 3773 } else { |
3631 while (values_to_process == 0 && !nested_counts.empty()) { | 3774 while (values_to_process == 0 && !nested_counts.empty()) { |
3632 values_to_process = nested_counts.top(); | 3775 values_to_process = nested_counts.top(); |
3633 nested_counts.pop(); | 3776 nested_counts.pop(); |
3634 } | 3777 } |
3635 } | 3778 } |
3636 } | 3779 } |
3637 } | 3780 } |
3638 | 3781 |
3639 CHECK(!iterator->HasNext() || | 3782 CHECK(!iterator->HasNext() || |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4238 CHECK(value_info->IsMaterializedObject()); | 4381 CHECK(value_info->IsMaterializedObject()); |
4239 | 4382 |
4240 value_info->value_ = | 4383 value_info->value_ = |
4241 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4384 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4242 } | 4385 } |
4243 } | 4386 } |
4244 } | 4387 } |
4245 | 4388 |
4246 } // namespace internal | 4389 } // namespace internal |
4247 } // namespace v8 | 4390 } // namespace v8 |
OLD | NEW |