| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 virtual void VisitFunction(JSFunction* function) { | 337 virtual void VisitFunction(JSFunction* function) { |
| 338 Code* code = function->code(); | 338 Code* code = function->code(); |
| 339 if (!code->marked_for_deoptimization()) return; | 339 if (!code->marked_for_deoptimization()) return; |
| 340 | 340 |
| 341 // Unlink this function and evict from optimized code map. | 341 // Unlink this function and evict from optimized code map. |
| 342 SharedFunctionInfo* shared = function->shared(); | 342 SharedFunctionInfo* shared = function->shared(); |
| 343 function->set_code(shared->code()); | 343 function->set_code(shared->code()); |
| 344 shared->EvictFromOptimizedCodeMap(code, "deoptimized function"); | 344 shared->EvictFromOptimizedCodeMap(code, "deoptimized function"); |
| 345 | 345 |
| 346 if (FLAG_trace_deopt) { | 346 if (FLAG_trace_deopt) { |
| 347 PrintF("[deoptimizer unlinked: "); | 347 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer()); |
| 348 function->PrintName(); | 348 PrintF(scope.file(), "[deoptimizer unlinked: "); |
| 349 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function)); | 349 function->PrintName(scope.file()); |
| 350 PrintF(scope.file(), |
| 351 " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function)); |
| 350 } | 352 } |
| 351 } | 353 } |
| 352 }; | 354 }; |
| 353 | 355 |
| 354 // Unlink all functions that refer to marked code. | 356 // Unlink all functions that refer to marked code. |
| 355 SelectedCodeUnlinker unlinker; | 357 SelectedCodeUnlinker unlinker; |
| 356 VisitAllOptimizedFunctionsForContext(context, &unlinker); | 358 VisitAllOptimizedFunctionsForContext(context, &unlinker); |
| 357 | 359 |
| 358 // Move marked code from the optimized code list to the deoptimized | 360 // Move marked code from the optimized code list to the deoptimized |
| 359 // code list, collecting them into a ZoneList. | 361 // code list, collecting them into a ZoneList. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 // We might be in the middle of incremental marking with compaction. | 404 // We might be in the middle of incremental marking with compaction. |
| 403 // Tell collector to treat this code object in a special way and | 405 // Tell collector to treat this code object in a special way and |
| 404 // ignore all slots that might have been recorded on it. | 406 // ignore all slots that might have been recorded on it. |
| 405 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]); | 407 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]); |
| 406 } | 408 } |
| 407 } | 409 } |
| 408 | 410 |
| 409 | 411 |
| 410 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { | 412 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { |
| 411 if (FLAG_trace_deopt) { | 413 if (FLAG_trace_deopt) { |
| 412 PrintF("[deoptimize all code in all contexts]\n"); | 414 CodeTracer::Scope scope(isolate->GetCodeTracer()); |
| 415 PrintF(scope.file(), "[deoptimize all code in all contexts]\n"); |
| 413 } | 416 } |
| 414 DisallowHeapAllocation no_allocation; | 417 DisallowHeapAllocation no_allocation; |
| 415 // For all contexts, mark all code, then deoptimize. | 418 // For all contexts, mark all code, then deoptimize. |
| 416 Object* context = isolate->heap()->native_contexts_list(); | 419 Object* context = isolate->heap()->native_contexts_list(); |
| 417 while (!context->IsUndefined()) { | 420 while (!context->IsUndefined()) { |
| 418 Context* native_context = Context::cast(context); | 421 Context* native_context = Context::cast(context); |
| 419 MarkAllCodeForContext(native_context); | 422 MarkAllCodeForContext(native_context); |
| 420 DeoptimizeMarkedCodeForContext(native_context); | 423 DeoptimizeMarkedCodeForContext(native_context); |
| 421 context = native_context->get(Context::NEXT_CONTEXT_LINK); | 424 context = native_context->get(Context::NEXT_CONTEXT_LINK); |
| 422 } | 425 } |
| 423 } | 426 } |
| 424 | 427 |
| 425 | 428 |
| 426 void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) { | 429 void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) { |
| 427 if (FLAG_trace_deopt) { | 430 if (FLAG_trace_deopt) { |
| 428 PrintF("[deoptimize marked code in all contexts]\n"); | 431 CodeTracer::Scope scope(isolate->GetCodeTracer()); |
| 432 PrintF(scope.file(), "[deoptimize marked code in all contexts]\n"); |
| 429 } | 433 } |
| 430 DisallowHeapAllocation no_allocation; | 434 DisallowHeapAllocation no_allocation; |
| 431 // For all contexts, deoptimize code already marked. | 435 // For all contexts, deoptimize code already marked. |
| 432 Object* context = isolate->heap()->native_contexts_list(); | 436 Object* context = isolate->heap()->native_contexts_list(); |
| 433 while (!context->IsUndefined()) { | 437 while (!context->IsUndefined()) { |
| 434 Context* native_context = Context::cast(context); | 438 Context* native_context = Context::cast(context); |
| 435 DeoptimizeMarkedCodeForContext(native_context); | 439 DeoptimizeMarkedCodeForContext(native_context); |
| 436 context = native_context->get(Context::NEXT_CONTEXT_LINK); | 440 context = native_context->get(Context::NEXT_CONTEXT_LINK); |
| 437 } | 441 } |
| 438 } | 442 } |
| 439 | 443 |
| 440 | 444 |
| 441 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { | 445 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { |
| 442 if (FLAG_trace_deopt) { | 446 if (FLAG_trace_deopt) { |
| 443 PrintF("[deoptimize global object @ 0x%08" V8PRIxPTR "]\n", | 447 CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer()); |
| 448 PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n", |
| 444 reinterpret_cast<intptr_t>(object)); | 449 reinterpret_cast<intptr_t>(object)); |
| 445 } | 450 } |
| 446 if (object->IsJSGlobalProxy()) { | 451 if (object->IsJSGlobalProxy()) { |
| 447 Object* proto = object->GetPrototype(); | 452 Object* proto = object->GetPrototype(); |
| 448 ASSERT(proto->IsJSGlobalObject()); | 453 ASSERT(proto->IsJSGlobalObject()); |
| 449 Context* native_context = GlobalObject::cast(proto)->native_context(); | 454 Context* native_context = GlobalObject::cast(proto)->native_context(); |
| 450 MarkAllCodeForContext(native_context); | 455 MarkAllCodeForContext(native_context); |
| 451 DeoptimizeMarkedCodeForContext(native_context); | 456 DeoptimizeMarkedCodeForContext(native_context); |
| 452 } else if (object->IsGlobalObject()) { | 457 } else if (object->IsGlobalObject()) { |
| 453 Context* native_context = GlobalObject::cast(object)->native_context(); | 458 Context* native_context = GlobalObject::cast(object)->native_context(); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 deferred_objects_tagged_values_(0), | 539 deferred_objects_tagged_values_(0), |
| 535 deferred_objects_double_values_(0), | 540 deferred_objects_double_values_(0), |
| 536 deferred_objects_(0), | 541 deferred_objects_(0), |
| 537 deferred_heap_numbers_(0), | 542 deferred_heap_numbers_(0), |
| 538 jsframe_functions_(0), | 543 jsframe_functions_(0), |
| 539 jsframe_has_adapted_arguments_(0), | 544 jsframe_has_adapted_arguments_(0), |
| 540 materialized_values_(NULL), | 545 materialized_values_(NULL), |
| 541 materialized_objects_(NULL), | 546 materialized_objects_(NULL), |
| 542 materialization_value_index_(0), | 547 materialization_value_index_(0), |
| 543 materialization_object_index_(0), | 548 materialization_object_index_(0), |
| 544 trace_(false) { | 549 trace_scope_(NULL) { |
| 545 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 550 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
| 546 // indicating an internal frame. | 551 // indicating an internal frame. |
| 547 if (function->IsSmi()) { | 552 if (function->IsSmi()) { |
| 548 function = NULL; | 553 function = NULL; |
| 549 } | 554 } |
| 550 ASSERT(from != NULL); | 555 ASSERT(from != NULL); |
| 551 if (function != NULL && function->IsOptimized()) { | 556 if (function != NULL && function->IsOptimized()) { |
| 552 function->shared()->increment_deopt_count(); | 557 function->shared()->increment_deopt_count(); |
| 553 if (bailout_type_ == Deoptimizer::SOFT) { | 558 if (bailout_type_ == Deoptimizer::SOFT) { |
| 554 isolate->counters()->soft_deopts_executed()->Increment(); | 559 isolate->counters()->soft_deopts_executed()->Increment(); |
| 555 // Soft deopts shouldn't count against the overall re-optimization count | 560 // Soft deopts shouldn't count against the overall re-optimization count |
| 556 // that can eventually lead to disabling optimization for a function. | 561 // that can eventually lead to disabling optimization for a function. |
| 557 int opt_count = function->shared()->opt_count(); | 562 int opt_count = function->shared()->opt_count(); |
| 558 if (opt_count > 0) opt_count--; | 563 if (opt_count > 0) opt_count--; |
| 559 function->shared()->set_opt_count(opt_count); | 564 function->shared()->set_opt_count(opt_count); |
| 560 } | 565 } |
| 561 } | 566 } |
| 562 compiled_code_ = FindOptimizedCode(function, optimized_code); | 567 compiled_code_ = FindOptimizedCode(function, optimized_code); |
| 563 | 568 |
| 564 #if DEBUG | 569 #if DEBUG |
| 565 ASSERT(compiled_code_ != NULL); | 570 ASSERT(compiled_code_ != NULL); |
| 566 if (type == EAGER || type == SOFT || type == LAZY) { | 571 if (type == EAGER || type == SOFT || type == LAZY) { |
| 567 ASSERT(compiled_code_->kind() != Code::FUNCTION); | 572 ASSERT(compiled_code_->kind() != Code::FUNCTION); |
| 568 } | 573 } |
| 569 #endif | 574 #endif |
| 570 | 575 |
| 571 StackFrame::Type frame_type = function == NULL | 576 StackFrame::Type frame_type = function == NULL |
| 572 ? StackFrame::STUB | 577 ? StackFrame::STUB |
| 573 : StackFrame::JAVA_SCRIPT; | 578 : StackFrame::JAVA_SCRIPT; |
| 574 trace_ = TraceEnabledFor(type, frame_type); | 579 trace_scope_ = TraceEnabledFor(type, frame_type) ? |
| 580 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; |
| 575 #ifdef DEBUG | 581 #ifdef DEBUG |
| 576 CHECK(AllowHeapAllocation::IsAllowed()); | 582 CHECK(AllowHeapAllocation::IsAllowed()); |
| 577 disallow_heap_allocation_ = new DisallowHeapAllocation(); | 583 disallow_heap_allocation_ = new DisallowHeapAllocation(); |
| 578 #endif // DEBUG | 584 #endif // DEBUG |
| 579 unsigned size = ComputeInputFrameSize(); | 585 unsigned size = ComputeInputFrameSize(); |
| 580 input_ = new(size) FrameDescription(size, function); | 586 input_ = new(size) FrameDescription(size, function); |
| 581 input_->SetFrameType(frame_type); | 587 input_->SetFrameType(frame_type); |
| 582 } | 588 } |
| 583 | 589 |
| 584 | 590 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 597 ASSERT(optimized_code->contains(from_)); | 603 ASSERT(optimized_code->contains(from_)); |
| 598 return optimized_code; | 604 return optimized_code; |
| 599 } | 605 } |
| 600 UNREACHABLE(); | 606 UNREACHABLE(); |
| 601 return NULL; | 607 return NULL; |
| 602 } | 608 } |
| 603 | 609 |
| 604 | 610 |
| 605 void Deoptimizer::PrintFunctionName() { | 611 void Deoptimizer::PrintFunctionName() { |
| 606 if (function_->IsJSFunction()) { | 612 if (function_->IsJSFunction()) { |
| 607 function_->PrintName(); | 613 function_->PrintName(trace_scope_->file()); |
| 608 } else { | 614 } else { |
| 609 PrintF("%s", Code::Kind2String(compiled_code_->kind())); | 615 PrintF(trace_scope_->file(), |
| 616 "%s", Code::Kind2String(compiled_code_->kind())); |
| 610 } | 617 } |
| 611 } | 618 } |
| 612 | 619 |
| 613 | 620 |
| 614 Deoptimizer::~Deoptimizer() { | 621 Deoptimizer::~Deoptimizer() { |
| 615 ASSERT(input_ == NULL && output_ == NULL); | 622 ASSERT(input_ == NULL && output_ == NULL); |
| 616 ASSERT(disallow_heap_allocation_ == NULL); | 623 ASSERT(disallow_heap_allocation_ == NULL); |
| 624 delete trace_scope_; |
| 617 } | 625 } |
| 618 | 626 |
| 619 | 627 |
| 620 void Deoptimizer::DeleteFrameDescriptions() { | 628 void Deoptimizer::DeleteFrameDescriptions() { |
| 621 delete input_; | 629 delete input_; |
| 622 for (int i = 0; i < output_count_; ++i) { | 630 for (int i = 0; i < output_count_; ++i) { |
| 623 if (output_[i] != input_) delete output_[i]; | 631 if (output_[i] != input_) delete output_[i]; |
| 624 } | 632 } |
| 625 delete[] output_; | 633 delete[] output_; |
| 626 input_ = NULL; | 634 input_ = NULL; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 SharedFunctionInfo* shared) { | 682 SharedFunctionInfo* shared) { |
| 675 // TODO(kasperl): For now, we do a simple linear search for the PC | 683 // TODO(kasperl): For now, we do a simple linear search for the PC |
| 676 // offset associated with the given node id. This should probably be | 684 // offset associated with the given node id. This should probably be |
| 677 // changed to a binary search. | 685 // changed to a binary search. |
| 678 int length = data->DeoptPoints(); | 686 int length = data->DeoptPoints(); |
| 679 for (int i = 0; i < length; i++) { | 687 for (int i = 0; i < length; i++) { |
| 680 if (data->AstId(i) == id) { | 688 if (data->AstId(i) == id) { |
| 681 return data->PcAndState(i)->value(); | 689 return data->PcAndState(i)->value(); |
| 682 } | 690 } |
| 683 } | 691 } |
| 684 PrintF("[couldn't find pc offset for node=%d]\n", id.ToInt()); | 692 PrintF(stderr, "[couldn't find pc offset for node=%d]\n", id.ToInt()); |
| 685 PrintF("[method: %s]\n", *shared->DebugName()->ToCString()); | 693 PrintF(stderr, "[method: %s]\n", *shared->DebugName()->ToCString()); |
| 686 // Print the source code if available. | 694 // Print the source code if available. |
| 687 HeapStringAllocator string_allocator; | 695 HeapStringAllocator string_allocator; |
| 688 StringStream stream(&string_allocator); | 696 StringStream stream(&string_allocator); |
| 689 shared->SourceCodePrint(&stream, -1); | 697 shared->SourceCodePrint(&stream, -1); |
| 690 PrintF("[source:\n%s\n]", *stream.ToCString()); | 698 PrintF(stderr, "[source:\n%s\n]", *stream.ToCString()); |
| 691 | 699 |
| 692 FATAL("unable to find pc offset during deoptimization"); | 700 FATAL("unable to find pc offset during deoptimization"); |
| 693 return -1; | 701 return -1; |
| 694 } | 702 } |
| 695 | 703 |
| 696 | 704 |
| 697 int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { | 705 int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { |
| 698 int length = 0; | 706 int length = 0; |
| 699 // Count all entries in the deoptimizing code list of every context. | 707 // Count all entries in the deoptimizing code list of every context. |
| 700 Object* context = isolate->heap()->native_contexts_list(); | 708 Object* context = isolate->heap()->native_contexts_list(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 715 | 723 |
| 716 // We rely on this function not causing a GC. It is called from generated code | 724 // We rely on this function not causing a GC. It is called from generated code |
| 717 // without having a real stack frame in place. | 725 // without having a real stack frame in place. |
| 718 void Deoptimizer::DoComputeOutputFrames() { | 726 void Deoptimizer::DoComputeOutputFrames() { |
| 719 // Print some helpful diagnostic information. | 727 // Print some helpful diagnostic information. |
| 720 if (FLAG_log_timer_events && | 728 if (FLAG_log_timer_events && |
| 721 compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 729 compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
| 722 LOG(isolate(), CodeDeoptEvent(compiled_code_)); | 730 LOG(isolate(), CodeDeoptEvent(compiled_code_)); |
| 723 } | 731 } |
| 724 ElapsedTimer timer; | 732 ElapsedTimer timer; |
| 725 if (trace_) { | 733 if (trace_scope_ != NULL) { |
| 726 timer.Start(); | 734 timer.Start(); |
| 727 PrintF("[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ", | 735 PrintF(trace_scope_->file(), |
| 736 "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ", |
| 728 MessageFor(bailout_type_), | 737 MessageFor(bailout_type_), |
| 729 reinterpret_cast<intptr_t>(function_)); | 738 reinterpret_cast<intptr_t>(function_)); |
| 730 PrintFunctionName(); | 739 PrintFunctionName(); |
| 731 PrintF(" @%d, FP to SP delta: %d]\n", bailout_id_, fp_to_sp_delta_); | 740 PrintF(trace_scope_->file(), |
| 741 " @%d, FP to SP delta: %d]\n", |
| 742 bailout_id_, |
| 743 fp_to_sp_delta_); |
| 732 if (bailout_type_ == EAGER || bailout_type_ == SOFT) { | 744 if (bailout_type_ == EAGER || bailout_type_ == SOFT) { |
| 733 compiled_code_->PrintDeoptLocation(bailout_id_); | 745 compiled_code_->PrintDeoptLocation(trace_scope_->file(), bailout_id_); |
| 734 } | 746 } |
| 735 } | 747 } |
| 736 | 748 |
| 737 // Determine basic deoptimization information. The optimized frame is | 749 // Determine basic deoptimization information. The optimized frame is |
| 738 // described by the input data. | 750 // described by the input data. |
| 739 DeoptimizationInputData* input_data = | 751 DeoptimizationInputData* input_data = |
| 740 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); | 752 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); |
| 741 BailoutId node_id = input_data->AstId(bailout_id_); | 753 BailoutId node_id = input_data->AstId(bailout_id_); |
| 742 ByteArray* translations = input_data->TranslationByteArray(); | 754 ByteArray* translations = input_data->TranslationByteArray(); |
| 743 unsigned translation_index = | 755 unsigned translation_index = |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 case Translation::DOUBLE_STACK_SLOT: | 808 case Translation::DOUBLE_STACK_SLOT: |
| 797 case Translation::LITERAL: | 809 case Translation::LITERAL: |
| 798 case Translation::ARGUMENTS_OBJECT: | 810 case Translation::ARGUMENTS_OBJECT: |
| 799 default: | 811 default: |
| 800 UNREACHABLE(); | 812 UNREACHABLE(); |
| 801 break; | 813 break; |
| 802 } | 814 } |
| 803 } | 815 } |
| 804 | 816 |
| 805 // Print some helpful diagnostic information. | 817 // Print some helpful diagnostic information. |
| 806 if (trace_) { | 818 if (trace_scope_ != NULL) { |
| 807 double ms = timer.Elapsed().InMillisecondsF(); | 819 double ms = timer.Elapsed().InMillisecondsF(); |
| 808 int index = output_count_ - 1; // Index of the topmost frame. | 820 int index = output_count_ - 1; // Index of the topmost frame. |
| 809 JSFunction* function = output_[index]->GetFunction(); | 821 JSFunction* function = output_[index]->GetFunction(); |
| 810 PrintF("[deoptimizing (%s): end 0x%08" V8PRIxPTR " ", | 822 PrintF(trace_scope_->file(), |
| 823 "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ", |
| 811 MessageFor(bailout_type_), | 824 MessageFor(bailout_type_), |
| 812 reinterpret_cast<intptr_t>(function)); | 825 reinterpret_cast<intptr_t>(function)); |
| 813 PrintFunctionName(); | 826 PrintFunctionName(); |
| 814 PrintF(" @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," | 827 PrintF(trace_scope_->file(), |
| 828 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," |
| 815 " took %0.3f ms]\n", | 829 " took %0.3f ms]\n", |
| 816 bailout_id_, | 830 bailout_id_, |
| 817 node_id.ToInt(), | 831 node_id.ToInt(), |
| 818 output_[index]->GetPc(), | 832 output_[index]->GetPc(), |
| 819 FullCodeGenerator::State2String( | 833 FullCodeGenerator::State2String( |
| 820 static_cast<FullCodeGenerator::State>( | 834 static_cast<FullCodeGenerator::State>( |
| 821 output_[index]->GetState()->value())), | 835 output_[index]->GetState()->value())), |
| 822 has_alignment_padding_ ? "with padding" : "no padding", | 836 has_alignment_padding_ ? "with padding" : "no padding", |
| 823 ms); | 837 ms); |
| 824 } | 838 } |
| 825 } | 839 } |
| 826 | 840 |
| 827 | 841 |
| 828 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 842 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
| 829 int frame_index) { | 843 int frame_index) { |
| 830 BailoutId node_id = BailoutId(iterator->Next()); | 844 BailoutId node_id = BailoutId(iterator->Next()); |
| 831 JSFunction* function; | 845 JSFunction* function; |
| 832 if (frame_index != 0) { | 846 if (frame_index != 0) { |
| 833 function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 847 function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 834 } else { | 848 } else { |
| 835 int closure_id = iterator->Next(); | 849 int closure_id = iterator->Next(); |
| 836 USE(closure_id); | 850 USE(closure_id); |
| 837 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); | 851 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); |
| 838 function = function_; | 852 function = function_; |
| 839 } | 853 } |
| 840 unsigned height = iterator->Next(); | 854 unsigned height = iterator->Next(); |
| 841 unsigned height_in_bytes = height * kPointerSize; | 855 unsigned height_in_bytes = height * kPointerSize; |
| 842 if (trace_) { | 856 if (trace_scope_ != NULL) { |
| 843 PrintF(" translating "); | 857 PrintF(trace_scope_->file(), " translating "); |
| 844 function->PrintName(); | 858 function->PrintName(trace_scope_->file()); |
| 845 PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 859 PrintF(trace_scope_->file(), |
| 860 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
| 846 } | 861 } |
| 847 | 862 |
| 848 // The 'fixed' part of the frame consists of the incoming parameters and | 863 // The 'fixed' part of the frame consists of the incoming parameters and |
| 849 // the part described by JavaScriptFrameConstants. | 864 // the part described by JavaScriptFrameConstants. |
| 850 unsigned fixed_frame_size = ComputeFixedSize(function); | 865 unsigned fixed_frame_size = ComputeFixedSize(function); |
| 851 unsigned input_frame_size = input_->GetFrameSize(); | 866 unsigned input_frame_size = input_->GetFrameSize(); |
| 852 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 867 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 853 | 868 |
| 854 // Allocate and store the output frame description. | 869 // Allocate and store the output frame description. |
| 855 FrameDescription* output_frame = | 870 FrameDescription* output_frame = |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 // function code and AST id of the bailout. | 917 // function code and AST id of the bailout. |
| 903 output_offset -= kPCOnStackSize; | 918 output_offset -= kPCOnStackSize; |
| 904 input_offset -= kPCOnStackSize; | 919 input_offset -= kPCOnStackSize; |
| 905 intptr_t value; | 920 intptr_t value; |
| 906 if (is_bottommost) { | 921 if (is_bottommost) { |
| 907 value = input_->GetFrameSlot(input_offset); | 922 value = input_->GetFrameSlot(input_offset); |
| 908 } else { | 923 } else { |
| 909 value = output_[frame_index - 1]->GetPc(); | 924 value = output_[frame_index - 1]->GetPc(); |
| 910 } | 925 } |
| 911 output_frame->SetCallerPc(output_offset, value); | 926 output_frame->SetCallerPc(output_offset, value); |
| 912 if (trace_) { | 927 if (trace_scope_ != NULL) { |
| 913 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 928 PrintF(trace_scope_->file(), |
| 929 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 914 V8PRIxPTR " ; caller's pc\n", | 930 V8PRIxPTR " ; caller's pc\n", |
| 915 top_address + output_offset, output_offset, value); | 931 top_address + output_offset, output_offset, value); |
| 916 } | 932 } |
| 917 | 933 |
| 918 // The caller's frame pointer for the bottommost output frame is the same | 934 // The caller's frame pointer for the bottommost output frame is the same |
| 919 // as in the input frame. For all subsequent output frames, it can be | 935 // as in the input frame. For all subsequent output frames, it can be |
| 920 // read from the previous one. Also compute and set this frame's frame | 936 // read from the previous one. Also compute and set this frame's frame |
| 921 // pointer. | 937 // pointer. |
| 922 output_offset -= kFPOnStackSize; | 938 output_offset -= kFPOnStackSize; |
| 923 input_offset -= kFPOnStackSize; | 939 input_offset -= kFPOnStackSize; |
| 924 if (is_bottommost) { | 940 if (is_bottommost) { |
| 925 value = input_->GetFrameSlot(input_offset); | 941 value = input_->GetFrameSlot(input_offset); |
| 926 } else { | 942 } else { |
| 927 value = output_[frame_index - 1]->GetFp(); | 943 value = output_[frame_index - 1]->GetFp(); |
| 928 } | 944 } |
| 929 output_frame->SetCallerFp(output_offset, value); | 945 output_frame->SetCallerFp(output_offset, value); |
| 930 intptr_t fp_value = top_address + output_offset; | 946 intptr_t fp_value = top_address + output_offset; |
| 931 ASSERT(!is_bottommost || (input_->GetRegister(fp_reg.code()) + | 947 ASSERT(!is_bottommost || (input_->GetRegister(fp_reg.code()) + |
| 932 has_alignment_padding_ * kPointerSize) == fp_value); | 948 has_alignment_padding_ * kPointerSize) == fp_value); |
| 933 output_frame->SetFp(fp_value); | 949 output_frame->SetFp(fp_value); |
| 934 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 950 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
| 935 if (trace_) { | 951 if (trace_scope_ != NULL) { |
| 936 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 952 PrintF(trace_scope_->file(), |
| 953 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 937 V8PRIxPTR " ; caller's fp\n", | 954 V8PRIxPTR " ; caller's fp\n", |
| 938 fp_value, output_offset, value); | 955 fp_value, output_offset, value); |
| 939 } | 956 } |
| 940 ASSERT(!is_bottommost || !has_alignment_padding_ || | 957 ASSERT(!is_bottommost || !has_alignment_padding_ || |
| 941 (fp_value & kPointerSize) != 0); | 958 (fp_value & kPointerSize) != 0); |
| 942 | 959 |
| 943 // For the bottommost output frame the context can be gotten from the input | 960 // For the bottommost output frame the context can be gotten from the input |
| 944 // frame. For all subsequent output frames it can be gotten from the function | 961 // frame. For all subsequent output frames it can be gotten from the function |
| 945 // so long as we don't inline functions that need local contexts. | 962 // so long as we don't inline functions that need local contexts. |
| 946 Register context_reg = JavaScriptFrame::context_register(); | 963 Register context_reg = JavaScriptFrame::context_register(); |
| 947 output_offset -= kPointerSize; | 964 output_offset -= kPointerSize; |
| 948 input_offset -= kPointerSize; | 965 input_offset -= kPointerSize; |
| 949 if (is_bottommost) { | 966 if (is_bottommost) { |
| 950 value = input_->GetFrameSlot(input_offset); | 967 value = input_->GetFrameSlot(input_offset); |
| 951 } else { | 968 } else { |
| 952 value = reinterpret_cast<intptr_t>(function->context()); | 969 value = reinterpret_cast<intptr_t>(function->context()); |
| 953 } | 970 } |
| 954 output_frame->SetFrameSlot(output_offset, value); | 971 output_frame->SetFrameSlot(output_offset, value); |
| 955 output_frame->SetContext(value); | 972 output_frame->SetContext(value); |
| 956 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); | 973 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); |
| 957 if (trace_) { | 974 if (trace_scope_ != NULL) { |
| 958 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 975 PrintF(trace_scope_->file(), |
| 976 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 959 V8PRIxPTR "; context\n", | 977 V8PRIxPTR "; context\n", |
| 960 top_address + output_offset, output_offset, value); | 978 top_address + output_offset, output_offset, value); |
| 961 } | 979 } |
| 962 | 980 |
| 963 // The function was mentioned explicitly in the BEGIN_FRAME. | 981 // The function was mentioned explicitly in the BEGIN_FRAME. |
| 964 output_offset -= kPointerSize; | 982 output_offset -= kPointerSize; |
| 965 input_offset -= kPointerSize; | 983 input_offset -= kPointerSize; |
| 966 value = reinterpret_cast<intptr_t>(function); | 984 value = reinterpret_cast<intptr_t>(function); |
| 967 // The function for the bottommost output frame should also agree with the | 985 // The function for the bottommost output frame should also agree with the |
| 968 // input frame. | 986 // input frame. |
| 969 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); | 987 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); |
| 970 output_frame->SetFrameSlot(output_offset, value); | 988 output_frame->SetFrameSlot(output_offset, value); |
| 971 if (trace_) { | 989 if (trace_scope_ != NULL) { |
| 972 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 990 PrintF(trace_scope_->file(), |
| 991 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 973 V8PRIxPTR "; function\n", | 992 V8PRIxPTR "; function\n", |
| 974 top_address + output_offset, output_offset, value); | 993 top_address + output_offset, output_offset, value); |
| 975 } | 994 } |
| 976 | 995 |
| 977 // Translate the rest of the frame. | 996 // Translate the rest of the frame. |
| 978 for (unsigned i = 0; i < height; ++i) { | 997 for (unsigned i = 0; i < height; ++i) { |
| 979 output_offset -= kPointerSize; | 998 output_offset -= kPointerSize; |
| 980 DoTranslateCommand(iterator, frame_index, output_offset); | 999 DoTranslateCommand(iterator, frame_index, output_offset); |
| 981 } | 1000 } |
| 982 ASSERT(0 == output_offset); | 1001 ASSERT(0 == output_offset); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1010 reinterpret_cast<intptr_t>(continuation->entry())); | 1029 reinterpret_cast<intptr_t>(continuation->entry())); |
| 1011 } | 1030 } |
| 1012 } | 1031 } |
| 1013 | 1032 |
| 1014 | 1033 |
| 1015 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, | 1034 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, |
| 1016 int frame_index) { | 1035 int frame_index) { |
| 1017 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 1036 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 1018 unsigned height = iterator->Next(); | 1037 unsigned height = iterator->Next(); |
| 1019 unsigned height_in_bytes = height * kPointerSize; | 1038 unsigned height_in_bytes = height * kPointerSize; |
| 1020 if (trace_) { | 1039 if (trace_scope_ != NULL) { |
| 1021 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); | 1040 PrintF(trace_scope_->file(), |
| 1041 " translating arguments adaptor => height=%d\n", height_in_bytes); |
| 1022 } | 1042 } |
| 1023 | 1043 |
| 1024 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; | 1044 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; |
| 1025 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1045 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 1026 | 1046 |
| 1027 // Allocate and store the output frame description. | 1047 // Allocate and store the output frame description. |
| 1028 FrameDescription* output_frame = | 1048 FrameDescription* output_frame = |
| 1029 new(output_frame_size) FrameDescription(output_frame_size, function); | 1049 new(output_frame_size) FrameDescription(output_frame_size, function); |
| 1030 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); | 1050 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
| 1031 | 1051 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1045 unsigned output_offset = output_frame_size; | 1065 unsigned output_offset = output_frame_size; |
| 1046 for (int i = 0; i < parameter_count; ++i) { | 1066 for (int i = 0; i < parameter_count; ++i) { |
| 1047 output_offset -= kPointerSize; | 1067 output_offset -= kPointerSize; |
| 1048 DoTranslateCommand(iterator, frame_index, output_offset); | 1068 DoTranslateCommand(iterator, frame_index, output_offset); |
| 1049 } | 1069 } |
| 1050 | 1070 |
| 1051 // Read caller's PC from the previous frame. | 1071 // Read caller's PC from the previous frame. |
| 1052 output_offset -= kPCOnStackSize; | 1072 output_offset -= kPCOnStackSize; |
| 1053 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1073 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
| 1054 output_frame->SetCallerPc(output_offset, callers_pc); | 1074 output_frame->SetCallerPc(output_offset, callers_pc); |
| 1055 if (trace_) { | 1075 if (trace_scope_ != NULL) { |
| 1056 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1076 PrintF(trace_scope_->file(), |
| 1077 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1057 V8PRIxPTR " ; caller's pc\n", | 1078 V8PRIxPTR " ; caller's pc\n", |
| 1058 top_address + output_offset, output_offset, callers_pc); | 1079 top_address + output_offset, output_offset, callers_pc); |
| 1059 } | 1080 } |
| 1060 | 1081 |
| 1061 // Read caller's FP from the previous frame, and set this frame's FP. | 1082 // Read caller's FP from the previous frame, and set this frame's FP. |
| 1062 output_offset -= kFPOnStackSize; | 1083 output_offset -= kFPOnStackSize; |
| 1063 intptr_t value = output_[frame_index - 1]->GetFp(); | 1084 intptr_t value = output_[frame_index - 1]->GetFp(); |
| 1064 output_frame->SetCallerFp(output_offset, value); | 1085 output_frame->SetCallerFp(output_offset, value); |
| 1065 intptr_t fp_value = top_address + output_offset; | 1086 intptr_t fp_value = top_address + output_offset; |
| 1066 output_frame->SetFp(fp_value); | 1087 output_frame->SetFp(fp_value); |
| 1067 if (trace_) { | 1088 if (trace_scope_ != NULL) { |
| 1068 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1089 PrintF(trace_scope_->file(), |
| 1090 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1069 V8PRIxPTR " ; caller's fp\n", | 1091 V8PRIxPTR " ; caller's fp\n", |
| 1070 fp_value, output_offset, value); | 1092 fp_value, output_offset, value); |
| 1071 } | 1093 } |
| 1072 | 1094 |
| 1073 // A marker value is used in place of the context. | 1095 // A marker value is used in place of the context. |
| 1074 output_offset -= kPointerSize; | 1096 output_offset -= kPointerSize; |
| 1075 intptr_t context = reinterpret_cast<intptr_t>( | 1097 intptr_t context = reinterpret_cast<intptr_t>( |
| 1076 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 1098 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 1077 output_frame->SetFrameSlot(output_offset, context); | 1099 output_frame->SetFrameSlot(output_offset, context); |
| 1078 if (trace_) { | 1100 if (trace_scope_ != NULL) { |
| 1079 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1101 PrintF(trace_scope_->file(), |
| 1102 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1080 V8PRIxPTR " ; context (adaptor sentinel)\n", | 1103 V8PRIxPTR " ; context (adaptor sentinel)\n", |
| 1081 top_address + output_offset, output_offset, context); | 1104 top_address + output_offset, output_offset, context); |
| 1082 } | 1105 } |
| 1083 | 1106 |
| 1084 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. | 1107 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. |
| 1085 output_offset -= kPointerSize; | 1108 output_offset -= kPointerSize; |
| 1086 value = reinterpret_cast<intptr_t>(function); | 1109 value = reinterpret_cast<intptr_t>(function); |
| 1087 output_frame->SetFrameSlot(output_offset, value); | 1110 output_frame->SetFrameSlot(output_offset, value); |
| 1088 if (trace_) { | 1111 if (trace_scope_ != NULL) { |
| 1089 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1112 PrintF(trace_scope_->file(), |
| 1113 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1090 V8PRIxPTR " ; function\n", | 1114 V8PRIxPTR " ; function\n", |
| 1091 top_address + output_offset, output_offset, value); | 1115 top_address + output_offset, output_offset, value); |
| 1092 } | 1116 } |
| 1093 | 1117 |
| 1094 // Number of incoming arguments. | 1118 // Number of incoming arguments. |
| 1095 output_offset -= kPointerSize; | 1119 output_offset -= kPointerSize; |
| 1096 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); | 1120 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); |
| 1097 output_frame->SetFrameSlot(output_offset, value); | 1121 output_frame->SetFrameSlot(output_offset, value); |
| 1098 if (trace_) { | 1122 if (trace_scope_ != NULL) { |
| 1099 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1123 PrintF(trace_scope_->file(), |
| 1124 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1100 V8PRIxPTR " ; argc (%d)\n", | 1125 V8PRIxPTR " ; argc (%d)\n", |
| 1101 top_address + output_offset, output_offset, value, height - 1); | 1126 top_address + output_offset, output_offset, value, height - 1); |
| 1102 } | 1127 } |
| 1103 | 1128 |
| 1104 ASSERT(0 == output_offset); | 1129 ASSERT(0 == output_offset); |
| 1105 | 1130 |
| 1106 Builtins* builtins = isolate_->builtins(); | 1131 Builtins* builtins = isolate_->builtins(); |
| 1107 Code* adaptor_trampoline = | 1132 Code* adaptor_trampoline = |
| 1108 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); | 1133 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); |
| 1109 intptr_t pc_value = reinterpret_cast<intptr_t>( | 1134 intptr_t pc_value = reinterpret_cast<intptr_t>( |
| 1110 adaptor_trampoline->instruction_start() + | 1135 adaptor_trampoline->instruction_start() + |
| 1111 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); | 1136 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); |
| 1112 output_frame->SetPc(pc_value); | 1137 output_frame->SetPc(pc_value); |
| 1113 } | 1138 } |
| 1114 | 1139 |
| 1115 | 1140 |
| 1116 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | 1141 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, |
| 1117 int frame_index) { | 1142 int frame_index) { |
| 1118 Builtins* builtins = isolate_->builtins(); | 1143 Builtins* builtins = isolate_->builtins(); |
| 1119 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 1144 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
| 1120 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 1145 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 1121 unsigned height = iterator->Next(); | 1146 unsigned height = iterator->Next(); |
| 1122 unsigned height_in_bytes = height * kPointerSize; | 1147 unsigned height_in_bytes = height * kPointerSize; |
| 1123 if (trace_) { | 1148 if (trace_scope_ != NULL) { |
| 1124 PrintF(" translating construct stub => height=%d\n", height_in_bytes); | 1149 PrintF(trace_scope_->file(), |
| 1150 " translating construct stub => height=%d\n", height_in_bytes); |
| 1125 } | 1151 } |
| 1126 | 1152 |
| 1127 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; | 1153 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; |
| 1128 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1154 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 1129 | 1155 |
| 1130 // Allocate and store the output frame description. | 1156 // Allocate and store the output frame description. |
| 1131 FrameDescription* output_frame = | 1157 FrameDescription* output_frame = |
| 1132 new(output_frame_size) FrameDescription(output_frame_size, function); | 1158 new(output_frame_size) FrameDescription(output_frame_size, function); |
| 1133 output_frame->SetFrameType(StackFrame::CONSTRUCT); | 1159 output_frame->SetFrameType(StackFrame::CONSTRUCT); |
| 1134 | 1160 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1156 if (i == 0 && deferred_objects_.length() > deferred_object_index) { | 1182 if (i == 0 && deferred_objects_.length() > deferred_object_index) { |
| 1157 ASSERT(!deferred_objects_[deferred_object_index].is_arguments()); | 1183 ASSERT(!deferred_objects_[deferred_object_index].is_arguments()); |
| 1158 deferred_objects_[deferred_object_index].patch_slot_address(top_address); | 1184 deferred_objects_[deferred_object_index].patch_slot_address(top_address); |
| 1159 } | 1185 } |
| 1160 } | 1186 } |
| 1161 | 1187 |
| 1162 // Read caller's PC from the previous frame. | 1188 // Read caller's PC from the previous frame. |
| 1163 output_offset -= kPCOnStackSize; | 1189 output_offset -= kPCOnStackSize; |
| 1164 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1190 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
| 1165 output_frame->SetCallerPc(output_offset, callers_pc); | 1191 output_frame->SetCallerPc(output_offset, callers_pc); |
| 1166 if (trace_) { | 1192 if (trace_scope_ != NULL) { |
| 1167 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1193 PrintF(trace_scope_->file(), |
| 1194 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1168 V8PRIxPTR " ; caller's pc\n", | 1195 V8PRIxPTR " ; caller's pc\n", |
| 1169 top_address + output_offset, output_offset, callers_pc); | 1196 top_address + output_offset, output_offset, callers_pc); |
| 1170 } | 1197 } |
| 1171 | 1198 |
| 1172 // Read caller's FP from the previous frame, and set this frame's FP. | 1199 // Read caller's FP from the previous frame, and set this frame's FP. |
| 1173 output_offset -= kFPOnStackSize; | 1200 output_offset -= kFPOnStackSize; |
| 1174 intptr_t value = output_[frame_index - 1]->GetFp(); | 1201 intptr_t value = output_[frame_index - 1]->GetFp(); |
| 1175 output_frame->SetCallerFp(output_offset, value); | 1202 output_frame->SetCallerFp(output_offset, value); |
| 1176 intptr_t fp_value = top_address + output_offset; | 1203 intptr_t fp_value = top_address + output_offset; |
| 1177 output_frame->SetFp(fp_value); | 1204 output_frame->SetFp(fp_value); |
| 1178 if (trace_) { | 1205 if (trace_scope_ != NULL) { |
| 1179 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1206 PrintF(trace_scope_->file(), |
| 1207 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1180 V8PRIxPTR " ; caller's fp\n", | 1208 V8PRIxPTR " ; caller's fp\n", |
| 1181 fp_value, output_offset, value); | 1209 fp_value, output_offset, value); |
| 1182 } | 1210 } |
| 1183 | 1211 |
| 1184 // The context can be gotten from the previous frame. | 1212 // The context can be gotten from the previous frame. |
| 1185 output_offset -= kPointerSize; | 1213 output_offset -= kPointerSize; |
| 1186 value = output_[frame_index - 1]->GetContext(); | 1214 value = output_[frame_index - 1]->GetContext(); |
| 1187 output_frame->SetFrameSlot(output_offset, value); | 1215 output_frame->SetFrameSlot(output_offset, value); |
| 1188 if (trace_) { | 1216 if (trace_scope_ != NULL) { |
| 1189 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1217 PrintF(trace_scope_->file(), |
| 1218 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1190 V8PRIxPTR " ; context\n", | 1219 V8PRIxPTR " ; context\n", |
| 1191 top_address + output_offset, output_offset, value); | 1220 top_address + output_offset, output_offset, value); |
| 1192 } | 1221 } |
| 1193 | 1222 |
| 1194 // A marker value is used in place of the function. | 1223 // A marker value is used in place of the function. |
| 1195 output_offset -= kPointerSize; | 1224 output_offset -= kPointerSize; |
| 1196 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); | 1225 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); |
| 1197 output_frame->SetFrameSlot(output_offset, value); | 1226 output_frame->SetFrameSlot(output_offset, value); |
| 1198 if (trace_) { | 1227 if (trace_scope_ != NULL) { |
| 1199 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1228 PrintF(trace_scope_->file(), |
| 1229 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1200 V8PRIxPTR " ; function (construct sentinel)\n", | 1230 V8PRIxPTR " ; function (construct sentinel)\n", |
| 1201 top_address + output_offset, output_offset, value); | 1231 top_address + output_offset, output_offset, value); |
| 1202 } | 1232 } |
| 1203 | 1233 |
| 1204 // The output frame reflects a JSConstructStubGeneric frame. | 1234 // The output frame reflects a JSConstructStubGeneric frame. |
| 1205 output_offset -= kPointerSize; | 1235 output_offset -= kPointerSize; |
| 1206 value = reinterpret_cast<intptr_t>(construct_stub); | 1236 value = reinterpret_cast<intptr_t>(construct_stub); |
| 1207 output_frame->SetFrameSlot(output_offset, value); | 1237 output_frame->SetFrameSlot(output_offset, value); |
| 1208 if (trace_) { | 1238 if (trace_scope_ != NULL) { |
| 1209 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1239 PrintF(trace_scope_->file(), |
| 1240 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1210 V8PRIxPTR " ; code object\n", | 1241 V8PRIxPTR " ; code object\n", |
| 1211 top_address + output_offset, output_offset, value); | 1242 top_address + output_offset, output_offset, value); |
| 1212 } | 1243 } |
| 1213 | 1244 |
| 1214 // Number of incoming arguments. | 1245 // Number of incoming arguments. |
| 1215 output_offset -= kPointerSize; | 1246 output_offset -= kPointerSize; |
| 1216 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); | 1247 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); |
| 1217 output_frame->SetFrameSlot(output_offset, value); | 1248 output_frame->SetFrameSlot(output_offset, value); |
| 1218 if (trace_) { | 1249 if (trace_scope_ != NULL) { |
| 1219 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1250 PrintF(trace_scope_->file(), |
| 1251 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1220 V8PRIxPTR " ; argc (%d)\n", | 1252 V8PRIxPTR " ; argc (%d)\n", |
| 1221 top_address + output_offset, output_offset, value, height - 1); | 1253 top_address + output_offset, output_offset, value, height - 1); |
| 1222 } | 1254 } |
| 1223 | 1255 |
| 1224 // Constructor function being invoked by the stub (only present on some | 1256 // Constructor function being invoked by the stub (only present on some |
| 1225 // architectures, indicated by kConstructorOffset). | 1257 // architectures, indicated by kConstructorOffset). |
| 1226 if (ConstructFrameConstants::kConstructorOffset != kMinInt) { | 1258 if (ConstructFrameConstants::kConstructorOffset != kMinInt) { |
| 1227 output_offset -= kPointerSize; | 1259 output_offset -= kPointerSize; |
| 1228 value = reinterpret_cast<intptr_t>(function); | 1260 value = reinterpret_cast<intptr_t>(function); |
| 1229 output_frame->SetFrameSlot(output_offset, value); | 1261 output_frame->SetFrameSlot(output_offset, value); |
| 1230 if (trace_) { | 1262 if (trace_scope_ != NULL) { |
| 1231 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1263 PrintF(trace_scope_->file(), |
| 1264 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1232 V8PRIxPTR " ; constructor function\n", | 1265 V8PRIxPTR " ; constructor function\n", |
| 1233 top_address + output_offset, output_offset, value); | 1266 top_address + output_offset, output_offset, value); |
| 1234 } | 1267 } |
| 1235 } | 1268 } |
| 1236 | 1269 |
| 1237 // The newly allocated object was passed as receiver in the artificial | 1270 // The newly allocated object was passed as receiver in the artificial |
| 1238 // constructor stub environment created by HEnvironment::CopyForInlining(). | 1271 // constructor stub environment created by HEnvironment::CopyForInlining(). |
| 1239 output_offset -= kPointerSize; | 1272 output_offset -= kPointerSize; |
| 1240 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); | 1273 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); |
| 1241 output_frame->SetFrameSlot(output_offset, value); | 1274 output_frame->SetFrameSlot(output_offset, value); |
| 1242 if (trace_) { | 1275 if (trace_scope_ != NULL) { |
| 1243 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1276 PrintF(trace_scope_->file(), |
| 1277 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1244 V8PRIxPTR " ; allocated receiver\n", | 1278 V8PRIxPTR " ; allocated receiver\n", |
| 1245 top_address + output_offset, output_offset, value); | 1279 top_address + output_offset, output_offset, value); |
| 1246 } | 1280 } |
| 1247 | 1281 |
| 1248 ASSERT(0 == output_offset); | 1282 ASSERT(0 == output_offset); |
| 1249 | 1283 |
| 1250 intptr_t pc = reinterpret_cast<intptr_t>( | 1284 intptr_t pc = reinterpret_cast<intptr_t>( |
| 1251 construct_stub->instruction_start() + | 1285 construct_stub->instruction_start() + |
| 1252 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 1286 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
| 1253 output_frame->SetPc(pc); | 1287 output_frame->SetPc(pc); |
| 1254 } | 1288 } |
| 1255 | 1289 |
| 1256 | 1290 |
| 1257 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, | 1291 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, |
| 1258 int frame_index, | 1292 int frame_index, |
| 1259 bool is_setter_stub_frame) { | 1293 bool is_setter_stub_frame) { |
| 1260 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); | 1294 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); |
| 1261 // The receiver (and the implicit return value, if any) are expected in | 1295 // The receiver (and the implicit return value, if any) are expected in |
| 1262 // registers by the LoadIC/StoreIC, so they don't belong to the output stack | 1296 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
| 1263 // frame. This means that we have to use a height of 0. | 1297 // frame. This means that we have to use a height of 0. |
| 1264 unsigned height = 0; | 1298 unsigned height = 0; |
| 1265 unsigned height_in_bytes = height * kPointerSize; | 1299 unsigned height_in_bytes = height * kPointerSize; |
| 1266 const char* kind = is_setter_stub_frame ? "setter" : "getter"; | 1300 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
| 1267 if (trace_) { | 1301 if (trace_scope_ != NULL) { |
| 1268 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); | 1302 PrintF(trace_scope_->file(), |
| 1303 " translating %s stub => height=%u\n", kind, height_in_bytes); |
| 1269 } | 1304 } |
| 1270 | 1305 |
| 1271 // We need 1 stack entry for the return address + 4 stack entries from | 1306 // We need 1 stack entry for the return address + 4 stack entries from |
| 1272 // StackFrame::INTERNAL (FP, context, frame type, code object, see | 1307 // StackFrame::INTERNAL (FP, context, frame type, code object, see |
| 1273 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional | 1308 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional |
| 1274 // entry for the implicit return value, see | 1309 // entry for the implicit return value, see |
| 1275 // StoreStubCompiler::CompileStoreViaSetter. | 1310 // StoreStubCompiler::CompileStoreViaSetter. |
| 1276 unsigned fixed_frame_entries = (kPCOnStackSize / kPointerSize) + | 1311 unsigned fixed_frame_entries = (kPCOnStackSize / kPointerSize) + |
| 1277 (kFPOnStackSize / kPointerSize) + 3 + | 1312 (kFPOnStackSize / kPointerSize) + 3 + |
| 1278 (is_setter_stub_frame ? 1 : 0); | 1313 (is_setter_stub_frame ? 1 : 0); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1293 // this frame's size. | 1328 // this frame's size. |
| 1294 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1329 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1295 output_frame->SetTop(top_address); | 1330 output_frame->SetTop(top_address); |
| 1296 | 1331 |
| 1297 unsigned output_offset = output_frame_size; | 1332 unsigned output_offset = output_frame_size; |
| 1298 | 1333 |
| 1299 // Read caller's PC from the previous frame. | 1334 // Read caller's PC from the previous frame. |
| 1300 output_offset -= kPCOnStackSize; | 1335 output_offset -= kPCOnStackSize; |
| 1301 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1336 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
| 1302 output_frame->SetCallerPc(output_offset, callers_pc); | 1337 output_frame->SetCallerPc(output_offset, callers_pc); |
| 1303 if (trace_) { | 1338 if (trace_scope_ != NULL) { |
| 1304 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 1339 PrintF(trace_scope_->file(), |
| 1340 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1305 " ; caller's pc\n", | 1341 " ; caller's pc\n", |
| 1306 top_address + output_offset, output_offset, callers_pc); | 1342 top_address + output_offset, output_offset, callers_pc); |
| 1307 } | 1343 } |
| 1308 | 1344 |
| 1309 // Read caller's FP from the previous frame, and set this frame's FP. | 1345 // Read caller's FP from the previous frame, and set this frame's FP. |
| 1310 output_offset -= kFPOnStackSize; | 1346 output_offset -= kFPOnStackSize; |
| 1311 intptr_t value = output_[frame_index - 1]->GetFp(); | 1347 intptr_t value = output_[frame_index - 1]->GetFp(); |
| 1312 output_frame->SetCallerFp(output_offset, value); | 1348 output_frame->SetCallerFp(output_offset, value); |
| 1313 intptr_t fp_value = top_address + output_offset; | 1349 intptr_t fp_value = top_address + output_offset; |
| 1314 output_frame->SetFp(fp_value); | 1350 output_frame->SetFp(fp_value); |
| 1315 if (trace_) { | 1351 if (trace_scope_ != NULL) { |
| 1316 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 1352 PrintF(trace_scope_->file(), |
| 1353 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1317 " ; caller's fp\n", | 1354 " ; caller's fp\n", |
| 1318 fp_value, output_offset, value); | 1355 fp_value, output_offset, value); |
| 1319 } | 1356 } |
| 1320 | 1357 |
| 1321 // The context can be gotten from the previous frame. | 1358 // The context can be gotten from the previous frame. |
| 1322 output_offset -= kPointerSize; | 1359 output_offset -= kPointerSize; |
| 1323 value = output_[frame_index - 1]->GetContext(); | 1360 value = output_[frame_index - 1]->GetContext(); |
| 1324 output_frame->SetFrameSlot(output_offset, value); | 1361 output_frame->SetFrameSlot(output_offset, value); |
| 1325 if (trace_) { | 1362 if (trace_scope_ != NULL) { |
| 1326 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 1363 PrintF(trace_scope_->file(), |
| 1364 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1327 " ; context\n", | 1365 " ; context\n", |
| 1328 top_address + output_offset, output_offset, value); | 1366 top_address + output_offset, output_offset, value); |
| 1329 } | 1367 } |
| 1330 | 1368 |
| 1331 // A marker value is used in place of the function. | 1369 // A marker value is used in place of the function. |
| 1332 output_offset -= kPointerSize; | 1370 output_offset -= kPointerSize; |
| 1333 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); | 1371 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); |
| 1334 output_frame->SetFrameSlot(output_offset, value); | 1372 output_frame->SetFrameSlot(output_offset, value); |
| 1335 if (trace_) { | 1373 if (trace_scope_ != NULL) { |
| 1336 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 1374 PrintF(trace_scope_->file(), |
| 1375 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1337 " ; function (%s sentinel)\n", | 1376 " ; function (%s sentinel)\n", |
| 1338 top_address + output_offset, output_offset, value, kind); | 1377 top_address + output_offset, output_offset, value, kind); |
| 1339 } | 1378 } |
| 1340 | 1379 |
| 1341 // Get Code object from accessor stub. | 1380 // Get Code object from accessor stub. |
| 1342 output_offset -= kPointerSize; | 1381 output_offset -= kPointerSize; |
| 1343 Builtins::Name name = is_setter_stub_frame ? | 1382 Builtins::Name name = is_setter_stub_frame ? |
| 1344 Builtins::kStoreIC_Setter_ForDeopt : | 1383 Builtins::kStoreIC_Setter_ForDeopt : |
| 1345 Builtins::kLoadIC_Getter_ForDeopt; | 1384 Builtins::kLoadIC_Getter_ForDeopt; |
| 1346 Code* accessor_stub = isolate_->builtins()->builtin(name); | 1385 Code* accessor_stub = isolate_->builtins()->builtin(name); |
| 1347 value = reinterpret_cast<intptr_t>(accessor_stub); | 1386 value = reinterpret_cast<intptr_t>(accessor_stub); |
| 1348 output_frame->SetFrameSlot(output_offset, value); | 1387 output_frame->SetFrameSlot(output_offset, value); |
| 1349 if (trace_) { | 1388 if (trace_scope_ != NULL) { |
| 1350 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 1389 PrintF(trace_scope_->file(), |
| 1390 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
| 1351 " ; code object\n", | 1391 " ; code object\n", |
| 1352 top_address + output_offset, output_offset, value); | 1392 top_address + output_offset, output_offset, value); |
| 1353 } | 1393 } |
| 1354 | 1394 |
| 1355 // Skip receiver. | 1395 // Skip receiver. |
| 1356 Translation::Opcode opcode = | 1396 Translation::Opcode opcode = |
| 1357 static_cast<Translation::Opcode>(iterator->Next()); | 1397 static_cast<Translation::Opcode>(iterator->Next()); |
| 1358 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | 1398 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
| 1359 | 1399 |
| 1360 if (is_setter_stub_frame) { | 1400 if (is_setter_stub_frame) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 // The output frame must have room for all pushed register parameters | 1456 // The output frame must have room for all pushed register parameters |
| 1417 // and the standard stack frame slots. Include space for an argument | 1457 // and the standard stack frame slots. Include space for an argument |
| 1418 // object to the callee and optionally the space to pass the argument | 1458 // object to the callee and optionally the space to pass the argument |
| 1419 // object to the stub failure handler. | 1459 // object to the stub failure handler. |
| 1420 ASSERT(descriptor->register_param_count_ >= 0); | 1460 ASSERT(descriptor->register_param_count_ >= 0); |
| 1421 int height_in_bytes = kPointerSize * descriptor->register_param_count_ + | 1461 int height_in_bytes = kPointerSize * descriptor->register_param_count_ + |
| 1422 sizeof(Arguments) + kPointerSize; | 1462 sizeof(Arguments) + kPointerSize; |
| 1423 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; | 1463 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; |
| 1424 int input_frame_size = input_->GetFrameSize(); | 1464 int input_frame_size = input_->GetFrameSize(); |
| 1425 int output_frame_size = height_in_bytes + fixed_frame_size; | 1465 int output_frame_size = height_in_bytes + fixed_frame_size; |
| 1426 if (trace_) { | 1466 if (trace_scope_ != NULL) { |
| 1427 PrintF(" translating %s => StubFailureTrampolineStub, height=%d\n", | 1467 PrintF(trace_scope_->file(), |
| 1468 " translating %s => StubFailureTrampolineStub, height=%d\n", |
| 1428 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), | 1469 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), |
| 1429 height_in_bytes); | 1470 height_in_bytes); |
| 1430 } | 1471 } |
| 1431 | 1472 |
| 1432 // The stub failure trampoline is a single frame. | 1473 // The stub failure trampoline is a single frame. |
| 1433 FrameDescription* output_frame = | 1474 FrameDescription* output_frame = |
| 1434 new(output_frame_size) FrameDescription(output_frame_size, NULL); | 1475 new(output_frame_size) FrameDescription(output_frame_size, NULL); |
| 1435 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 1476 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 1436 ASSERT(frame_index == 0); | 1477 ASSERT(frame_index == 0); |
| 1437 output_[frame_index] = output_frame; | 1478 output_[frame_index] = output_frame; |
| 1438 | 1479 |
| 1439 // The top address for the output frame can be computed from the input | 1480 // The top address for the output frame can be computed from the input |
| 1440 // frame pointer and the output frame's height. Subtract space for the | 1481 // frame pointer and the output frame's height. Subtract space for the |
| 1441 // context and function slots. | 1482 // context and function slots. |
| 1442 Register fp_reg = StubFailureTrampolineFrame::fp_register(); | 1483 Register fp_reg = StubFailureTrampolineFrame::fp_register(); |
| 1443 intptr_t top_address = input_->GetRegister(fp_reg.code()) - | 1484 intptr_t top_address = input_->GetRegister(fp_reg.code()) - |
| 1444 (2 * kPointerSize) - height_in_bytes; | 1485 (2 * kPointerSize) - height_in_bytes; |
| 1445 output_frame->SetTop(top_address); | 1486 output_frame->SetTop(top_address); |
| 1446 | 1487 |
| 1447 // Read caller's PC (JSFunction continuation) from the input frame. | 1488 // Read caller's PC (JSFunction continuation) from the input frame. |
| 1448 unsigned input_frame_offset = input_frame_size - kPCOnStackSize; | 1489 unsigned input_frame_offset = input_frame_size - kPCOnStackSize; |
| 1449 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; | 1490 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; |
| 1450 intptr_t value = input_->GetFrameSlot(input_frame_offset); | 1491 intptr_t value = input_->GetFrameSlot(input_frame_offset); |
| 1451 output_frame->SetCallerPc(output_frame_offset, value); | 1492 output_frame->SetCallerPc(output_frame_offset, value); |
| 1452 if (trace_) { | 1493 if (trace_scope_ != NULL) { |
| 1453 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1494 PrintF(trace_scope_->file(), |
| 1495 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1454 V8PRIxPTR " ; caller's pc\n", | 1496 V8PRIxPTR " ; caller's pc\n", |
| 1455 top_address + output_frame_offset, output_frame_offset, value); | 1497 top_address + output_frame_offset, output_frame_offset, value); |
| 1456 } | 1498 } |
| 1457 | 1499 |
| 1458 // Read caller's FP from the input frame, and set this frame's FP. | 1500 // Read caller's FP from the input frame, and set this frame's FP. |
| 1459 input_frame_offset -= kFPOnStackSize; | 1501 input_frame_offset -= kFPOnStackSize; |
| 1460 value = input_->GetFrameSlot(input_frame_offset); | 1502 value = input_->GetFrameSlot(input_frame_offset); |
| 1461 output_frame_offset -= kFPOnStackSize; | 1503 output_frame_offset -= kFPOnStackSize; |
| 1462 output_frame->SetCallerFp(output_frame_offset, value); | 1504 output_frame->SetCallerFp(output_frame_offset, value); |
| 1463 intptr_t frame_ptr = input_->GetRegister(fp_reg.code()); | 1505 intptr_t frame_ptr = input_->GetRegister(fp_reg.code()); |
| 1464 output_frame->SetRegister(fp_reg.code(), frame_ptr); | 1506 output_frame->SetRegister(fp_reg.code(), frame_ptr); |
| 1465 output_frame->SetFp(frame_ptr); | 1507 output_frame->SetFp(frame_ptr); |
| 1466 if (trace_) { | 1508 if (trace_scope_ != NULL) { |
| 1467 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1509 PrintF(trace_scope_->file(), |
| 1510 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1468 V8PRIxPTR " ; caller's fp\n", | 1511 V8PRIxPTR " ; caller's fp\n", |
| 1469 top_address + output_frame_offset, output_frame_offset, value); | 1512 top_address + output_frame_offset, output_frame_offset, value); |
| 1470 } | 1513 } |
| 1471 | 1514 |
| 1472 // The context can be gotten from the input frame. | 1515 // The context can be gotten from the input frame. |
| 1473 Register context_reg = StubFailureTrampolineFrame::context_register(); | 1516 Register context_reg = StubFailureTrampolineFrame::context_register(); |
| 1474 input_frame_offset -= kPointerSize; | 1517 input_frame_offset -= kPointerSize; |
| 1475 value = input_->GetFrameSlot(input_frame_offset); | 1518 value = input_->GetFrameSlot(input_frame_offset); |
| 1476 output_frame->SetRegister(context_reg.code(), value); | 1519 output_frame->SetRegister(context_reg.code(), value); |
| 1477 output_frame_offset -= kPointerSize; | 1520 output_frame_offset -= kPointerSize; |
| 1478 output_frame->SetFrameSlot(output_frame_offset, value); | 1521 output_frame->SetFrameSlot(output_frame_offset, value); |
| 1479 if (trace_) { | 1522 if (trace_scope_ != NULL) { |
| 1480 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1523 PrintF(trace_scope_->file(), |
| 1524 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1481 V8PRIxPTR " ; context\n", | 1525 V8PRIxPTR " ; context\n", |
| 1482 top_address + output_frame_offset, output_frame_offset, value); | 1526 top_address + output_frame_offset, output_frame_offset, value); |
| 1483 } | 1527 } |
| 1484 | 1528 |
| 1485 // A marker value is used in place of the function. | 1529 // A marker value is used in place of the function. |
| 1486 output_frame_offset -= kPointerSize; | 1530 output_frame_offset -= kPointerSize; |
| 1487 value = reinterpret_cast<intptr_t>( | 1531 value = reinterpret_cast<intptr_t>( |
| 1488 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); | 1532 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); |
| 1489 output_frame->SetFrameSlot(output_frame_offset, value); | 1533 output_frame->SetFrameSlot(output_frame_offset, value); |
| 1490 if (trace_) { | 1534 if (trace_scope_ != NULL) { |
| 1491 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1535 PrintF(trace_scope_->file(), |
| 1536 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1492 V8PRIxPTR " ; function (stub failure sentinel)\n", | 1537 V8PRIxPTR " ; function (stub failure sentinel)\n", |
| 1493 top_address + output_frame_offset, output_frame_offset, value); | 1538 top_address + output_frame_offset, output_frame_offset, value); |
| 1494 } | 1539 } |
| 1495 | 1540 |
| 1496 intptr_t caller_arg_count = 0; | 1541 intptr_t caller_arg_count = 0; |
| 1497 bool arg_count_known = !descriptor->stack_parameter_count_.is_valid(); | 1542 bool arg_count_known = !descriptor->stack_parameter_count_.is_valid(); |
| 1498 | 1543 |
| 1499 // Build the Arguments object for the caller's parameters and a pointer to it. | 1544 // Build the Arguments object for the caller's parameters and a pointer to it. |
| 1500 output_frame_offset -= kPointerSize; | 1545 output_frame_offset -= kPointerSize; |
| 1501 int args_arguments_offset = output_frame_offset; | 1546 int args_arguments_offset = output_frame_offset; |
| 1502 intptr_t the_hole = reinterpret_cast<intptr_t>( | 1547 intptr_t the_hole = reinterpret_cast<intptr_t>( |
| 1503 isolate_->heap()->the_hole_value()); | 1548 isolate_->heap()->the_hole_value()); |
| 1504 if (arg_count_known) { | 1549 if (arg_count_known) { |
| 1505 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 1550 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + |
| 1506 (caller_arg_count - 1) * kPointerSize; | 1551 (caller_arg_count - 1) * kPointerSize; |
| 1507 } else { | 1552 } else { |
| 1508 value = the_hole; | 1553 value = the_hole; |
| 1509 } | 1554 } |
| 1510 | 1555 |
| 1511 output_frame->SetFrameSlot(args_arguments_offset, value); | 1556 output_frame->SetFrameSlot(args_arguments_offset, value); |
| 1512 if (trace_) { | 1557 if (trace_scope_ != NULL) { |
| 1513 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1558 PrintF(trace_scope_->file(), |
| 1559 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1514 V8PRIxPTR " ; args.arguments %s\n", | 1560 V8PRIxPTR " ; args.arguments %s\n", |
| 1515 top_address + args_arguments_offset, args_arguments_offset, value, | 1561 top_address + args_arguments_offset, args_arguments_offset, value, |
| 1516 arg_count_known ? "" : "(the hole)"); | 1562 arg_count_known ? "" : "(the hole)"); |
| 1517 } | 1563 } |
| 1518 | 1564 |
| 1519 output_frame_offset -= kPointerSize; | 1565 output_frame_offset -= kPointerSize; |
| 1520 int length_frame_offset = output_frame_offset; | 1566 int length_frame_offset = output_frame_offset; |
| 1521 value = arg_count_known ? caller_arg_count : the_hole; | 1567 value = arg_count_known ? caller_arg_count : the_hole; |
| 1522 output_frame->SetFrameSlot(length_frame_offset, value); | 1568 output_frame->SetFrameSlot(length_frame_offset, value); |
| 1523 if (trace_) { | 1569 if (trace_scope_ != NULL) { |
| 1524 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1570 PrintF(trace_scope_->file(), |
| 1571 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1525 V8PRIxPTR " ; args.length %s\n", | 1572 V8PRIxPTR " ; args.length %s\n", |
| 1526 top_address + length_frame_offset, length_frame_offset, value, | 1573 top_address + length_frame_offset, length_frame_offset, value, |
| 1527 arg_count_known ? "" : "(the hole)"); | 1574 arg_count_known ? "" : "(the hole)"); |
| 1528 } | 1575 } |
| 1529 | 1576 |
| 1530 output_frame_offset -= kPointerSize; | 1577 output_frame_offset -= kPointerSize; |
| 1531 value = frame_ptr + StandardFrameConstants::kCallerSPOffset - | 1578 value = frame_ptr + StandardFrameConstants::kCallerSPOffset - |
| 1532 (output_frame_size - output_frame_offset) + kPointerSize; | 1579 (output_frame_size - output_frame_offset) + kPointerSize; |
| 1533 output_frame->SetFrameSlot(output_frame_offset, value); | 1580 output_frame->SetFrameSlot(output_frame_offset, value); |
| 1534 if (trace_) { | 1581 if (trace_scope_ != NULL) { |
| 1535 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1582 PrintF(trace_scope_->file(), |
| 1583 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1536 V8PRIxPTR " ; args*\n", | 1584 V8PRIxPTR " ; args*\n", |
| 1537 top_address + output_frame_offset, output_frame_offset, value); | 1585 top_address + output_frame_offset, output_frame_offset, value); |
| 1538 } | 1586 } |
| 1539 | 1587 |
| 1540 // Copy the register parameters to the failure frame. | 1588 // Copy the register parameters to the failure frame. |
| 1589 int arguments_length_offset = -1; |
| 1541 for (int i = 0; i < descriptor->register_param_count_; ++i) { | 1590 for (int i = 0; i < descriptor->register_param_count_; ++i) { |
| 1542 output_frame_offset -= kPointerSize; | 1591 output_frame_offset -= kPointerSize; |
| 1543 DoTranslateCommand(iterator, 0, output_frame_offset); | 1592 DoTranslateCommand(iterator, 0, output_frame_offset); |
| 1544 } | |
| 1545 | 1593 |
| 1546 if (!arg_count_known) { | 1594 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) { |
| 1547 DoTranslateCommand(iterator, 0, length_frame_offset, | 1595 arguments_length_offset = output_frame_offset; |
| 1548 TRANSLATED_VALUE_IS_NATIVE); | |
| 1549 caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); | |
| 1550 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | |
| 1551 (caller_arg_count - 1) * kPointerSize; | |
| 1552 output_frame->SetFrameSlot(args_arguments_offset, value); | |
| 1553 if (trace_) { | |
| 1554 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | |
| 1555 V8PRIxPTR " ; args.arguments\n", | |
| 1556 top_address + args_arguments_offset, args_arguments_offset, value); | |
| 1557 } | 1596 } |
| 1558 } | 1597 } |
| 1559 | 1598 |
| 1560 ASSERT(0 == output_frame_offset); | 1599 ASSERT(0 == output_frame_offset); |
| 1561 | 1600 |
| 1601 if (!arg_count_known) { |
| 1602 ASSERT(arguments_length_offset >= 0); |
| 1603 // We know it's a smi because 1) the code stub guarantees the stack |
| 1604 // parameter count is in smi range, and 2) the DoTranslateCommand in the |
| 1605 // parameter loop above translated that to a tagged value. |
| 1606 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( |
| 1607 output_frame->GetFrameSlot(arguments_length_offset)); |
| 1608 caller_arg_count = smi_caller_arg_count->value(); |
| 1609 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); |
| 1610 if (trace_scope_ != NULL) { |
| 1611 PrintF(trace_scope_->file(), |
| 1612 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1613 V8PRIxPTR " ; args.length\n", |
| 1614 top_address + length_frame_offset, length_frame_offset, |
| 1615 caller_arg_count); |
| 1616 } |
| 1617 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + |
| 1618 (caller_arg_count - 1) * kPointerSize; |
| 1619 output_frame->SetFrameSlot(args_arguments_offset, value); |
| 1620 if (trace_scope_ != NULL) { |
| 1621 PrintF(trace_scope_->file(), |
| 1622 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1623 V8PRIxPTR " ; args.arguments\n", |
| 1624 top_address + args_arguments_offset, args_arguments_offset, |
| 1625 value); |
| 1626 } |
| 1627 } |
| 1628 |
| 1562 // Copy the double registers from the input into the output frame. | 1629 // Copy the double registers from the input into the output frame. |
| 1563 CopyDoubleRegisters(output_frame); | 1630 CopyDoubleRegisters(output_frame); |
| 1564 | 1631 |
| 1565 // Fill registers containing handler and number of parameters. | 1632 // Fill registers containing handler and number of parameters. |
| 1566 SetPlatformCompiledStubRegisters(output_frame, descriptor); | 1633 SetPlatformCompiledStubRegisters(output_frame, descriptor); |
| 1567 | 1634 |
| 1568 // Compute this frame's PC, state, and continuation. | 1635 // Compute this frame's PC, state, and continuation. |
| 1569 Code* trampoline = NULL; | 1636 Code* trampoline = NULL; |
| 1570 StubFunctionMode function_mode = descriptor->function_mode_; | 1637 StubFunctionMode function_mode = descriptor->function_mode_; |
| 1571 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, | 1638 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 array->set(i, *value); | 1680 array->set(i, *value); |
| 1614 } | 1681 } |
| 1615 } else { | 1682 } else { |
| 1616 // Dispatch on the instance type of the object to be materialized. | 1683 // Dispatch on the instance type of the object to be materialized. |
| 1617 // We also need to make sure that the representation of all fields | 1684 // We also need to make sure that the representation of all fields |
| 1618 // in the given object are general enough to hold a tagged value. | 1685 // in the given object are general enough to hold a tagged value. |
| 1619 Handle<Map> map = Map::GeneralizeAllFieldRepresentations( | 1686 Handle<Map> map = Map::GeneralizeAllFieldRepresentations( |
| 1620 Handle<Map>::cast(MaterializeNextValue()), Representation::Tagged()); | 1687 Handle<Map>::cast(MaterializeNextValue()), Representation::Tagged()); |
| 1621 switch (map->instance_type()) { | 1688 switch (map->instance_type()) { |
| 1622 case HEAP_NUMBER_TYPE: { | 1689 case HEAP_NUMBER_TYPE: { |
| 1623 Handle<HeapNumber> object = isolate_->factory()->NewHeapNumber(0.0); | 1690 // Reuse the HeapNumber value directly as it is already properly |
| 1691 // tagged and skip materializing the HeapNumber explicitly. |
| 1692 Handle<Object> object = MaterializeNextValue(); |
| 1624 materialized_objects_->Add(object); | 1693 materialized_objects_->Add(object); |
| 1625 Handle<Object> number = MaterializeNextValue(); | |
| 1626 object->set_value(number->Number()); | |
| 1627 materialization_value_index_ += kDoubleSize / kPointerSize - 1; | 1694 materialization_value_index_ += kDoubleSize / kPointerSize - 1; |
| 1628 break; | 1695 break; |
| 1629 } | 1696 } |
| 1630 case JS_OBJECT_TYPE: { | 1697 case JS_OBJECT_TYPE: { |
| 1631 Handle<JSObject> object = | 1698 Handle<JSObject> object = |
| 1632 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); | 1699 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); |
| 1633 materialized_objects_->Add(object); | 1700 materialized_objects_->Add(object); |
| 1634 Handle<Object> properties = MaterializeNextValue(); | 1701 Handle<Object> properties = MaterializeNextValue(); |
| 1635 Handle<Object> elements = MaterializeNextValue(); | 1702 Handle<Object> elements = MaterializeNextValue(); |
| 1636 object->set_properties(FixedArray::cast(*properties)); | 1703 object->set_properties(FixedArray::cast(*properties)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1647 materialized_objects_->Add(object); | 1714 materialized_objects_->Add(object); |
| 1648 Handle<Object> properties = MaterializeNextValue(); | 1715 Handle<Object> properties = MaterializeNextValue(); |
| 1649 Handle<Object> elements = MaterializeNextValue(); | 1716 Handle<Object> elements = MaterializeNextValue(); |
| 1650 Handle<Object> length = MaterializeNextValue(); | 1717 Handle<Object> length = MaterializeNextValue(); |
| 1651 object->set_properties(FixedArray::cast(*properties)); | 1718 object->set_properties(FixedArray::cast(*properties)); |
| 1652 object->set_elements(FixedArrayBase::cast(*elements)); | 1719 object->set_elements(FixedArrayBase::cast(*elements)); |
| 1653 object->set_length(*length); | 1720 object->set_length(*length); |
| 1654 break; | 1721 break; |
| 1655 } | 1722 } |
| 1656 default: | 1723 default: |
| 1657 PrintF("[couldn't handle instance type %d]\n", map->instance_type()); | 1724 PrintF(stderr, |
| 1725 "[couldn't handle instance type %d]\n", map->instance_type()); |
| 1658 UNREACHABLE(); | 1726 UNREACHABLE(); |
| 1659 } | 1727 } |
| 1660 } | 1728 } |
| 1661 | 1729 |
| 1662 return materialized_objects_->at(object_index); | 1730 return materialized_objects_->at(object_index); |
| 1663 } | 1731 } |
| 1664 | 1732 |
| 1665 | 1733 |
| 1666 Handle<Object> Deoptimizer::MaterializeNextValue() { | 1734 Handle<Object> Deoptimizer::MaterializeNextValue() { |
| 1667 int value_index = materialization_value_index_++; | 1735 int value_index = materialization_value_index_++; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1692 | 1760 |
| 1693 // Play it safe and clear all unhandlified values before we continue. | 1761 // Play it safe and clear all unhandlified values before we continue. |
| 1694 deferred_objects_tagged_values_.Clear(); | 1762 deferred_objects_tagged_values_.Clear(); |
| 1695 | 1763 |
| 1696 // Materialize all heap numbers before looking at arguments because when the | 1764 // Materialize all heap numbers before looking at arguments because when the |
| 1697 // output frames are used to materialize arguments objects later on they need | 1765 // output frames are used to materialize arguments objects later on they need |
| 1698 // to already contain valid heap numbers. | 1766 // to already contain valid heap numbers. |
| 1699 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { | 1767 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { |
| 1700 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; | 1768 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; |
| 1701 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1769 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1702 if (trace_) { | 1770 if (trace_scope_ != NULL) { |
| 1703 PrintF("Materialized a new heap number %p [%e] in slot %p\n", | 1771 PrintF(trace_scope_->file(), |
| 1772 "Materialized a new heap number %p [%e] in slot %p\n", |
| 1704 reinterpret_cast<void*>(*num), | 1773 reinterpret_cast<void*>(*num), |
| 1705 d.value(), | 1774 d.value(), |
| 1706 d.destination()); | 1775 d.destination()); |
| 1707 } | 1776 } |
| 1708 Memory::Object_at(d.destination()) = *num; | 1777 Memory::Object_at(d.destination()) = *num; |
| 1709 } | 1778 } |
| 1710 | 1779 |
| 1711 // Materialize all heap numbers required for arguments/captured objects. | 1780 // Materialize all heap numbers required for arguments/captured objects. |
| 1712 for (int i = 0; i < deferred_objects_double_values_.length(); i++) { | 1781 for (int i = 0; i < deferred_objects_double_values_.length(); i++) { |
| 1713 HeapNumberMaterializationDescriptor<int> d = | 1782 HeapNumberMaterializationDescriptor<int> d = |
| 1714 deferred_objects_double_values_[i]; | 1783 deferred_objects_double_values_[i]; |
| 1715 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1784 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1716 if (trace_) { | 1785 if (trace_scope_ != NULL) { |
| 1717 PrintF("Materialized a new heap number %p [%e] for object at %d\n", | 1786 PrintF(trace_scope_->file(), |
| 1787 "Materialized a new heap number %p [%e] for object at %d\n", |
| 1718 reinterpret_cast<void*>(*num), | 1788 reinterpret_cast<void*>(*num), |
| 1719 d.value(), | 1789 d.value(), |
| 1720 d.destination()); | 1790 d.destination()); |
| 1721 } | 1791 } |
| 1722 ASSERT(values.at(d.destination())->IsTheHole()); | 1792 ASSERT(values.at(d.destination())->IsTheHole()); |
| 1723 values.Set(d.destination(), num); | 1793 values.Set(d.destination(), num); |
| 1724 } | 1794 } |
| 1725 | 1795 |
| 1726 // Play it safe and clear all object double values before we continue. | 1796 // Play it safe and clear all object double values before we continue. |
| 1727 deferred_objects_double_values_.Clear(); | 1797 deferred_objects_double_values_.Clear(); |
| 1728 | 1798 |
| 1729 // Materialize arguments/captured objects. | 1799 // Materialize arguments/captured objects. |
| 1730 if (!deferred_objects_.is_empty()) { | 1800 if (!deferred_objects_.is_empty()) { |
| 1731 List<Handle<Object> > materialized_objects(deferred_objects_.length()); | 1801 List<Handle<Object> > materialized_objects(deferred_objects_.length()); |
| 1732 materialized_objects_ = &materialized_objects; | 1802 materialized_objects_ = &materialized_objects; |
| 1733 materialized_values_ = &values; | 1803 materialized_values_ = &values; |
| 1734 | 1804 |
| 1735 while (materialization_object_index_ < deferred_objects_.length()) { | 1805 while (materialization_object_index_ < deferred_objects_.length()) { |
| 1736 int object_index = materialization_object_index_; | 1806 int object_index = materialization_object_index_; |
| 1737 ObjectMaterializationDescriptor descriptor = | 1807 ObjectMaterializationDescriptor descriptor = |
| 1738 deferred_objects_.at(object_index); | 1808 deferred_objects_.at(object_index); |
| 1739 | 1809 |
| 1740 // Find a previously materialized object by de-duplication or | 1810 // Find a previously materialized object by de-duplication or |
| 1741 // materialize a new instance of the object if necessary. Store | 1811 // materialize a new instance of the object if necessary. Store |
| 1742 // the materialized object into the frame slot. | 1812 // the materialized object into the frame slot. |
| 1743 Handle<Object> object = MaterializeNextHeapObject(); | 1813 Handle<Object> object = MaterializeNextHeapObject(); |
| 1744 Memory::Object_at(descriptor.slot_address()) = *object; | 1814 Memory::Object_at(descriptor.slot_address()) = *object; |
| 1745 if (trace_) { | 1815 if (trace_scope_ != NULL) { |
| 1746 if (descriptor.is_arguments()) { | 1816 if (descriptor.is_arguments()) { |
| 1747 PrintF("Materialized %sarguments object of length %d for %p: ", | 1817 PrintF(trace_scope_->file(), |
| 1818 "Materialized %sarguments object of length %d for %p: ", |
| 1748 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", | 1819 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", |
| 1749 Handle<JSObject>::cast(object)->elements()->length(), | 1820 Handle<JSObject>::cast(object)->elements()->length(), |
| 1750 reinterpret_cast<void*>(descriptor.slot_address())); | 1821 reinterpret_cast<void*>(descriptor.slot_address())); |
| 1751 } else { | 1822 } else { |
| 1752 PrintF("Materialized captured object of size %d for %p: ", | 1823 PrintF(trace_scope_->file(), |
| 1824 "Materialized captured object of size %d for %p: ", |
| 1753 Handle<HeapObject>::cast(object)->Size(), | 1825 Handle<HeapObject>::cast(object)->Size(), |
| 1754 reinterpret_cast<void*>(descriptor.slot_address())); | 1826 reinterpret_cast<void*>(descriptor.slot_address())); |
| 1755 } | 1827 } |
| 1756 object->ShortPrint(); | 1828 object->ShortPrint(trace_scope_->file()); |
| 1757 PrintF("\n"); | 1829 PrintF(trace_scope_->file(), "\n"); |
| 1758 } | 1830 } |
| 1759 } | 1831 } |
| 1760 | 1832 |
| 1761 ASSERT(materialization_object_index_ == materialized_objects_->length()); | 1833 ASSERT(materialization_object_index_ == materialized_objects_->length()); |
| 1762 ASSERT(materialization_value_index_ == materialized_values_->length()); | 1834 ASSERT(materialization_value_index_ == materialized_values_->length()); |
| 1763 } | 1835 } |
| 1764 } | 1836 } |
| 1765 | 1837 |
| 1766 | 1838 |
| 1767 #ifdef ENABLE_DEBUGGER_SUPPORT | 1839 #ifdef ENABLE_DEBUGGER_SUPPORT |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1779 | 1851 |
| 1780 // Check of the heap number to materialize actually belong to the frame | 1852 // Check of the heap number to materialize actually belong to the frame |
| 1781 // being extracted. | 1853 // being extracted. |
| 1782 Address slot = d.destination(); | 1854 Address slot = d.destination(); |
| 1783 if (parameters_top <= slot && slot < parameters_bottom) { | 1855 if (parameters_top <= slot && slot < parameters_bottom) { |
| 1784 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1856 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1785 | 1857 |
| 1786 int index = (info->parameters_count() - 1) - | 1858 int index = (info->parameters_count() - 1) - |
| 1787 static_cast<int>(slot - parameters_top) / kPointerSize; | 1859 static_cast<int>(slot - parameters_top) / kPointerSize; |
| 1788 | 1860 |
| 1789 if (trace_) { | 1861 if (trace_scope_ != NULL) { |
| 1790 PrintF("Materializing a new heap number %p [%e] in slot %p" | 1862 PrintF(trace_scope_->file(), |
| 1863 "Materializing a new heap number %p [%e] in slot %p" |
| 1791 "for parameter slot #%d\n", | 1864 "for parameter slot #%d\n", |
| 1792 reinterpret_cast<void*>(*num), | 1865 reinterpret_cast<void*>(*num), |
| 1793 d.value(), | 1866 d.value(), |
| 1794 d.destination(), | 1867 d.destination(), |
| 1795 index); | 1868 index); |
| 1796 } | 1869 } |
| 1797 | 1870 |
| 1798 info->SetParameter(index, *num); | 1871 info->SetParameter(index, *num); |
| 1799 } else if (expressions_top <= slot && slot < expressions_bottom) { | 1872 } else if (expressions_top <= slot && slot < expressions_bottom) { |
| 1800 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1873 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1801 | 1874 |
| 1802 int index = info->expression_count() - 1 - | 1875 int index = info->expression_count() - 1 - |
| 1803 static_cast<int>(slot - expressions_top) / kPointerSize; | 1876 static_cast<int>(slot - expressions_top) / kPointerSize; |
| 1804 | 1877 |
| 1805 if (trace_) { | 1878 if (trace_scope_ != NULL) { |
| 1806 PrintF("Materializing a new heap number %p [%e] in slot %p" | 1879 PrintF(trace_scope_->file(), |
| 1880 "Materializing a new heap number %p [%e] in slot %p" |
| 1807 "for expression slot #%d\n", | 1881 "for expression slot #%d\n", |
| 1808 reinterpret_cast<void*>(*num), | 1882 reinterpret_cast<void*>(*num), |
| 1809 d.value(), | 1883 d.value(), |
| 1810 d.destination(), | 1884 d.destination(), |
| 1811 index); | 1885 index); |
| 1812 } | 1886 } |
| 1813 | 1887 |
| 1814 info->SetExpression(index, *num); | 1888 info->SetExpression(index, *num); |
| 1815 } | 1889 } |
| 1816 } | 1890 } |
| 1817 } | 1891 } |
| 1818 #endif | 1892 #endif |
| 1819 | 1893 |
| 1820 | 1894 |
| 1821 static const char* TraceValueType(bool is_smi, bool is_native = false) { | 1895 static const char* TraceValueType(bool is_smi) { |
| 1822 if (is_native) { | 1896 if (is_smi) { |
| 1823 return "native"; | |
| 1824 } else if (is_smi) { | |
| 1825 return "smi"; | 1897 return "smi"; |
| 1826 } | 1898 } |
| 1827 | 1899 |
| 1828 return "heap number"; | 1900 return "heap number"; |
| 1829 } | 1901 } |
| 1830 | 1902 |
| 1831 | 1903 |
| 1832 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, | 1904 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
| 1833 int object_index, | 1905 int object_index, |
| 1834 int field_index) { | 1906 int field_index) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1845 case Translation::CONSTRUCT_STUB_FRAME: | 1917 case Translation::CONSTRUCT_STUB_FRAME: |
| 1846 case Translation::GETTER_STUB_FRAME: | 1918 case Translation::GETTER_STUB_FRAME: |
| 1847 case Translation::SETTER_STUB_FRAME: | 1919 case Translation::SETTER_STUB_FRAME: |
| 1848 case Translation::COMPILED_STUB_FRAME: | 1920 case Translation::COMPILED_STUB_FRAME: |
| 1849 UNREACHABLE(); | 1921 UNREACHABLE(); |
| 1850 return; | 1922 return; |
| 1851 | 1923 |
| 1852 case Translation::REGISTER: { | 1924 case Translation::REGISTER: { |
| 1853 int input_reg = iterator->Next(); | 1925 int input_reg = iterator->Next(); |
| 1854 intptr_t input_value = input_->GetRegister(input_reg); | 1926 intptr_t input_value = input_->GetRegister(input_reg); |
| 1855 if (trace_) { | 1927 if (trace_scope_ != NULL) { |
| 1856 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1928 PrintF(trace_scope_->file(), |
| 1929 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1857 reinterpret_cast<intptr_t>(object_slot), | 1930 reinterpret_cast<intptr_t>(object_slot), |
| 1858 field_index); | 1931 field_index); |
| 1859 PrintF("0x%08" V8PRIxPTR " ; %s ", input_value, | 1932 PrintF(trace_scope_->file(), |
| 1933 "0x%08" V8PRIxPTR " ; %s ", input_value, |
| 1860 converter.NameOfCPURegister(input_reg)); | 1934 converter.NameOfCPURegister(input_reg)); |
| 1861 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 1935 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 1862 PrintF("\n"); | 1936 trace_scope_->file()); |
| 1937 PrintF(trace_scope_->file(), |
| 1938 "\n"); |
| 1863 } | 1939 } |
| 1864 AddObjectTaggedValue(input_value); | 1940 AddObjectTaggedValue(input_value); |
| 1865 return; | 1941 return; |
| 1866 } | 1942 } |
| 1867 | 1943 |
| 1868 case Translation::INT32_REGISTER: { | 1944 case Translation::INT32_REGISTER: { |
| 1869 int input_reg = iterator->Next(); | 1945 int input_reg = iterator->Next(); |
| 1870 intptr_t value = input_->GetRegister(input_reg); | 1946 intptr_t value = input_->GetRegister(input_reg); |
| 1871 bool is_smi = Smi::IsValid(value); | 1947 bool is_smi = Smi::IsValid(value); |
| 1872 if (trace_) { | 1948 if (trace_scope_ != NULL) { |
| 1873 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1949 PrintF(trace_scope_->file(), |
| 1950 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1874 reinterpret_cast<intptr_t>(object_slot), | 1951 reinterpret_cast<intptr_t>(object_slot), |
| 1875 field_index); | 1952 field_index); |
| 1876 PrintF("%" V8PRIdPTR " ; %s (%s)\n", value, | 1953 PrintF(trace_scope_->file(), |
| 1954 "%" V8PRIdPTR " ; %s (%s)\n", value, |
| 1877 converter.NameOfCPURegister(input_reg), | 1955 converter.NameOfCPURegister(input_reg), |
| 1878 TraceValueType(is_smi)); | 1956 TraceValueType(is_smi)); |
| 1879 } | 1957 } |
| 1880 if (is_smi) { | 1958 if (is_smi) { |
| 1881 intptr_t tagged_value = | 1959 intptr_t tagged_value = |
| 1882 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1960 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1883 AddObjectTaggedValue(tagged_value); | 1961 AddObjectTaggedValue(tagged_value); |
| 1884 } else { | 1962 } else { |
| 1885 double double_value = static_cast<double>(static_cast<int32_t>(value)); | 1963 double double_value = static_cast<double>(static_cast<int32_t>(value)); |
| 1886 AddObjectDoubleValue(double_value); | 1964 AddObjectDoubleValue(double_value); |
| 1887 } | 1965 } |
| 1888 return; | 1966 return; |
| 1889 } | 1967 } |
| 1890 | 1968 |
| 1891 case Translation::UINT32_REGISTER: { | 1969 case Translation::UINT32_REGISTER: { |
| 1892 int input_reg = iterator->Next(); | 1970 int input_reg = iterator->Next(); |
| 1893 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 1971 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); |
| 1894 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 1972 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 1895 if (trace_) { | 1973 if (trace_scope_ != NULL) { |
| 1896 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1974 PrintF(trace_scope_->file(), |
| 1975 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1897 reinterpret_cast<intptr_t>(object_slot), | 1976 reinterpret_cast<intptr_t>(object_slot), |
| 1898 field_index); | 1977 field_index); |
| 1899 PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value, | 1978 PrintF(trace_scope_->file(), |
| 1979 "%" V8PRIdPTR " ; uint %s (%s)\n", value, |
| 1900 converter.NameOfCPURegister(input_reg), | 1980 converter.NameOfCPURegister(input_reg), |
| 1901 TraceValueType(is_smi)); | 1981 TraceValueType(is_smi)); |
| 1902 } | 1982 } |
| 1903 if (is_smi) { | 1983 if (is_smi) { |
| 1904 intptr_t tagged_value = | 1984 intptr_t tagged_value = |
| 1905 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1985 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1906 AddObjectTaggedValue(tagged_value); | 1986 AddObjectTaggedValue(tagged_value); |
| 1907 } else { | 1987 } else { |
| 1908 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | 1988 double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
| 1909 AddObjectDoubleValue(double_value); | 1989 AddObjectDoubleValue(double_value); |
| 1910 } | 1990 } |
| 1911 return; | 1991 return; |
| 1912 } | 1992 } |
| 1913 | 1993 |
| 1914 case Translation::DOUBLE_REGISTER: { | 1994 case Translation::DOUBLE_REGISTER: { |
| 1915 int input_reg = iterator->Next(); | 1995 int input_reg = iterator->Next(); |
| 1916 double value = input_->GetDoubleRegister(input_reg); | 1996 double value = input_->GetDoubleRegister(input_reg); |
| 1917 if (trace_) { | 1997 if (trace_scope_ != NULL) { |
| 1918 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1998 PrintF(trace_scope_->file(), |
| 1999 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1919 reinterpret_cast<intptr_t>(object_slot), | 2000 reinterpret_cast<intptr_t>(object_slot), |
| 1920 field_index); | 2001 field_index); |
| 1921 PrintF("%e ; %s\n", value, | 2002 PrintF(trace_scope_->file(), |
| 2003 "%e ; %s\n", value, |
| 1922 DoubleRegister::AllocationIndexToString(input_reg)); | 2004 DoubleRegister::AllocationIndexToString(input_reg)); |
| 1923 } | 2005 } |
| 1924 AddObjectDoubleValue(value); | 2006 AddObjectDoubleValue(value); |
| 1925 return; | 2007 return; |
| 1926 } | 2008 } |
| 1927 | 2009 |
| 1928 case Translation::STACK_SLOT: { | 2010 case Translation::STACK_SLOT: { |
| 1929 int input_slot_index = iterator->Next(); | 2011 int input_slot_index = iterator->Next(); |
| 1930 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2012 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1931 intptr_t input_value = input_->GetFrameSlot(input_offset); | 2013 intptr_t input_value = input_->GetFrameSlot(input_offset); |
| 1932 if (trace_) { | 2014 if (trace_scope_ != NULL) { |
| 1933 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2015 PrintF(trace_scope_->file(), |
| 2016 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1934 reinterpret_cast<intptr_t>(object_slot), | 2017 reinterpret_cast<intptr_t>(object_slot), |
| 1935 field_index); | 2018 field_index); |
| 1936 PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); | 2019 PrintF(trace_scope_->file(), |
| 1937 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2020 "0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); |
| 1938 PrintF("\n"); | 2021 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2022 trace_scope_->file()); |
| 2023 PrintF(trace_scope_->file(), |
| 2024 "\n"); |
| 1939 } | 2025 } |
| 1940 AddObjectTaggedValue(input_value); | 2026 AddObjectTaggedValue(input_value); |
| 1941 return; | 2027 return; |
| 1942 } | 2028 } |
| 1943 | 2029 |
| 1944 case Translation::INT32_STACK_SLOT: { | 2030 case Translation::INT32_STACK_SLOT: { |
| 1945 int input_slot_index = iterator->Next(); | 2031 int input_slot_index = iterator->Next(); |
| 1946 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2032 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1947 intptr_t value = input_->GetFrameSlot(input_offset); | 2033 intptr_t value = input_->GetFrameSlot(input_offset); |
| 1948 bool is_smi = Smi::IsValid(value); | 2034 bool is_smi = Smi::IsValid(value); |
| 1949 if (trace_) { | 2035 if (trace_scope_ != NULL) { |
| 1950 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2036 PrintF(trace_scope_->file(), |
| 2037 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1951 reinterpret_cast<intptr_t>(object_slot), | 2038 reinterpret_cast<intptr_t>(object_slot), |
| 1952 field_index); | 2039 field_index); |
| 1953 PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n", | 2040 PrintF(trace_scope_->file(), |
| 2041 "%" V8PRIdPTR " ; [sp + %d] (%s)\n", |
| 1954 value, input_offset, TraceValueType(is_smi)); | 2042 value, input_offset, TraceValueType(is_smi)); |
| 1955 } | 2043 } |
| 1956 if (is_smi) { | 2044 if (is_smi) { |
| 1957 intptr_t tagged_value = | 2045 intptr_t tagged_value = |
| 1958 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2046 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1959 AddObjectTaggedValue(tagged_value); | 2047 AddObjectTaggedValue(tagged_value); |
| 1960 } else { | 2048 } else { |
| 1961 double double_value = static_cast<double>(static_cast<int32_t>(value)); | 2049 double double_value = static_cast<double>(static_cast<int32_t>(value)); |
| 1962 AddObjectDoubleValue(double_value); | 2050 AddObjectDoubleValue(double_value); |
| 1963 } | 2051 } |
| 1964 return; | 2052 return; |
| 1965 } | 2053 } |
| 1966 | 2054 |
| 1967 case Translation::UINT32_STACK_SLOT: { | 2055 case Translation::UINT32_STACK_SLOT: { |
| 1968 int input_slot_index = iterator->Next(); | 2056 int input_slot_index = iterator->Next(); |
| 1969 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2057 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1970 uintptr_t value = | 2058 uintptr_t value = |
| 1971 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 2059 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
| 1972 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2060 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 1973 if (trace_) { | 2061 if (trace_scope_ != NULL) { |
| 1974 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2062 PrintF(trace_scope_->file(), |
| 2063 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1975 reinterpret_cast<intptr_t>(object_slot), | 2064 reinterpret_cast<intptr_t>(object_slot), |
| 1976 field_index); | 2065 field_index); |
| 1977 PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", | 2066 PrintF(trace_scope_->file(), |
| 2067 "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", |
| 1978 value, input_offset, TraceValueType(is_smi)); | 2068 value, input_offset, TraceValueType(is_smi)); |
| 1979 } | 2069 } |
| 1980 if (is_smi) { | 2070 if (is_smi) { |
| 1981 intptr_t tagged_value = | 2071 intptr_t tagged_value = |
| 1982 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2072 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1983 AddObjectTaggedValue(tagged_value); | 2073 AddObjectTaggedValue(tagged_value); |
| 1984 } else { | 2074 } else { |
| 1985 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | 2075 double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
| 1986 AddObjectDoubleValue(double_value); | 2076 AddObjectDoubleValue(double_value); |
| 1987 } | 2077 } |
| 1988 return; | 2078 return; |
| 1989 } | 2079 } |
| 1990 | 2080 |
| 1991 case Translation::DOUBLE_STACK_SLOT: { | 2081 case Translation::DOUBLE_STACK_SLOT: { |
| 1992 int input_slot_index = iterator->Next(); | 2082 int input_slot_index = iterator->Next(); |
| 1993 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2083 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1994 double value = input_->GetDoubleFrameSlot(input_offset); | 2084 double value = input_->GetDoubleFrameSlot(input_offset); |
| 1995 if (trace_) { | 2085 if (trace_scope_ != NULL) { |
| 1996 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2086 PrintF(trace_scope_->file(), |
| 2087 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1997 reinterpret_cast<intptr_t>(object_slot), | 2088 reinterpret_cast<intptr_t>(object_slot), |
| 1998 field_index); | 2089 field_index); |
| 1999 PrintF("%e ; [sp + %d]\n", value, input_offset); | 2090 PrintF(trace_scope_->file(), |
| 2091 "%e ; [sp + %d]\n", value, input_offset); |
| 2000 } | 2092 } |
| 2001 AddObjectDoubleValue(value); | 2093 AddObjectDoubleValue(value); |
| 2002 return; | 2094 return; |
| 2003 } | 2095 } |
| 2004 | 2096 |
| 2005 case Translation::LITERAL: { | 2097 case Translation::LITERAL: { |
| 2006 Object* literal = ComputeLiteral(iterator->Next()); | 2098 Object* literal = ComputeLiteral(iterator->Next()); |
| 2007 if (trace_) { | 2099 if (trace_scope_ != NULL) { |
| 2008 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2100 PrintF(trace_scope_->file(), |
| 2101 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2009 reinterpret_cast<intptr_t>(object_slot), | 2102 reinterpret_cast<intptr_t>(object_slot), |
| 2010 field_index); | 2103 field_index); |
| 2011 literal->ShortPrint(); | 2104 literal->ShortPrint(trace_scope_->file()); |
| 2012 PrintF(" ; literal\n"); | 2105 PrintF(trace_scope_->file(), |
| 2106 " ; literal\n"); |
| 2013 } | 2107 } |
| 2014 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2108 intptr_t value = reinterpret_cast<intptr_t>(literal); |
| 2015 AddObjectTaggedValue(value); | 2109 AddObjectTaggedValue(value); |
| 2016 return; | 2110 return; |
| 2017 } | 2111 } |
| 2018 | 2112 |
| 2019 case Translation::DUPLICATED_OBJECT: { | 2113 case Translation::DUPLICATED_OBJECT: { |
| 2020 int object_index = iterator->Next(); | 2114 int object_index = iterator->Next(); |
| 2021 if (trace_) { | 2115 if (trace_scope_ != NULL) { |
| 2022 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2116 PrintF(trace_scope_->file(), |
| 2117 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2023 reinterpret_cast<intptr_t>(object_slot), | 2118 reinterpret_cast<intptr_t>(object_slot), |
| 2024 field_index); | 2119 field_index); |
| 2025 isolate_->heap()->arguments_marker()->ShortPrint(); | 2120 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2026 PrintF(" ; duplicate of object #%d\n", object_index); | 2121 PrintF(trace_scope_->file(), |
| 2122 " ; duplicate of object #%d\n", object_index); |
| 2027 } | 2123 } |
| 2028 // Use the materialization marker value as a sentinel and fill in | 2124 // Use the materialization marker value as a sentinel and fill in |
| 2029 // the object after the deoptimized frame is built. | 2125 // the object after the deoptimized frame is built. |
| 2030 intptr_t value = reinterpret_cast<intptr_t>( | 2126 intptr_t value = reinterpret_cast<intptr_t>( |
| 2031 isolate_->heap()->arguments_marker()); | 2127 isolate_->heap()->arguments_marker()); |
| 2032 AddObjectDuplication(0, object_index); | 2128 AddObjectDuplication(0, object_index); |
| 2033 AddObjectTaggedValue(value); | 2129 AddObjectTaggedValue(value); |
| 2034 return; | 2130 return; |
| 2035 } | 2131 } |
| 2036 | 2132 |
| 2037 case Translation::ARGUMENTS_OBJECT: | 2133 case Translation::ARGUMENTS_OBJECT: |
| 2038 case Translation::CAPTURED_OBJECT: { | 2134 case Translation::CAPTURED_OBJECT: { |
| 2039 int length = iterator->Next(); | 2135 int length = iterator->Next(); |
| 2040 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; | 2136 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2041 if (trace_) { | 2137 if (trace_scope_ != NULL) { |
| 2042 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2138 PrintF(trace_scope_->file(), |
| 2139 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2043 reinterpret_cast<intptr_t>(object_slot), | 2140 reinterpret_cast<intptr_t>(object_slot), |
| 2044 field_index); | 2141 field_index); |
| 2045 isolate_->heap()->arguments_marker()->ShortPrint(); | 2142 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2046 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); | 2143 PrintF(trace_scope_->file(), |
| 2144 " ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2047 } | 2145 } |
| 2048 // Use the materialization marker value as a sentinel and fill in | 2146 // Use the materialization marker value as a sentinel and fill in |
| 2049 // the object after the deoptimized frame is built. | 2147 // the object after the deoptimized frame is built. |
| 2050 intptr_t value = reinterpret_cast<intptr_t>( | 2148 intptr_t value = reinterpret_cast<intptr_t>( |
| 2051 isolate_->heap()->arguments_marker()); | 2149 isolate_->heap()->arguments_marker()); |
| 2052 AddObjectStart(0, length, is_args); | 2150 AddObjectStart(0, length, is_args); |
| 2053 AddObjectTaggedValue(value); | 2151 AddObjectTaggedValue(value); |
| 2054 // We save the object values on the side and materialize the actual | 2152 // We save the object values on the side and materialize the actual |
| 2055 // object after the deoptimized frame is built. | 2153 // object after the deoptimized frame is built. |
| 2056 int object_index = deferred_objects_.length() - 1; | 2154 int object_index = deferred_objects_.length() - 1; |
| 2057 for (int i = 0; i < length; i++) { | 2155 for (int i = 0; i < length; i++) { |
| 2058 DoTranslateObject(iterator, object_index, i); | 2156 DoTranslateObject(iterator, object_index, i); |
| 2059 } | 2157 } |
| 2060 return; | 2158 return; |
| 2061 } | 2159 } |
| 2062 } | 2160 } |
| 2063 } | 2161 } |
| 2064 | 2162 |
| 2065 | 2163 |
| 2066 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 2164 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
| 2067 int frame_index, | 2165 int frame_index, |
| 2068 unsigned output_offset, | 2166 unsigned output_offset) { |
| 2069 DeoptimizerTranslatedValueType value_type) { | |
| 2070 disasm::NameConverter converter; | 2167 disasm::NameConverter converter; |
| 2071 // A GC-safe temporary placeholder that we can put in the output frame. | 2168 // A GC-safe temporary placeholder that we can put in the output frame. |
| 2072 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 2169 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 2073 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; | |
| 2074 | 2170 |
| 2075 Translation::Opcode opcode = | 2171 Translation::Opcode opcode = |
| 2076 static_cast<Translation::Opcode>(iterator->Next()); | 2172 static_cast<Translation::Opcode>(iterator->Next()); |
| 2077 | 2173 |
| 2078 switch (opcode) { | 2174 switch (opcode) { |
| 2079 case Translation::BEGIN: | 2175 case Translation::BEGIN: |
| 2080 case Translation::JS_FRAME: | 2176 case Translation::JS_FRAME: |
| 2081 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 2177 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 2082 case Translation::CONSTRUCT_STUB_FRAME: | 2178 case Translation::CONSTRUCT_STUB_FRAME: |
| 2083 case Translation::GETTER_STUB_FRAME: | 2179 case Translation::GETTER_STUB_FRAME: |
| 2084 case Translation::SETTER_STUB_FRAME: | 2180 case Translation::SETTER_STUB_FRAME: |
| 2085 case Translation::COMPILED_STUB_FRAME: | 2181 case Translation::COMPILED_STUB_FRAME: |
| 2086 UNREACHABLE(); | 2182 UNREACHABLE(); |
| 2087 return; | 2183 return; |
| 2088 | 2184 |
| 2089 case Translation::REGISTER: { | 2185 case Translation::REGISTER: { |
| 2090 int input_reg = iterator->Next(); | 2186 int input_reg = iterator->Next(); |
| 2091 intptr_t input_value = input_->GetRegister(input_reg); | 2187 intptr_t input_value = input_->GetRegister(input_reg); |
| 2092 if (trace_) { | 2188 if (trace_scope_ != NULL) { |
| 2093 PrintF( | 2189 PrintF( |
| 2190 trace_scope_->file(), |
| 2094 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 2191 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
| 2095 output_[frame_index]->GetTop() + output_offset, | 2192 output_[frame_index]->GetTop() + output_offset, |
| 2096 output_offset, | 2193 output_offset, |
| 2097 input_value, | 2194 input_value, |
| 2098 converter.NameOfCPURegister(input_reg)); | 2195 converter.NameOfCPURegister(input_reg)); |
| 2099 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2196 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2100 PrintF("\n"); | 2197 trace_scope_->file()); |
| 2198 PrintF(trace_scope_->file(), "\n"); |
| 2101 } | 2199 } |
| 2102 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 2200 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
| 2103 return; | 2201 return; |
| 2104 } | 2202 } |
| 2105 | 2203 |
| 2106 case Translation::INT32_REGISTER: { | 2204 case Translation::INT32_REGISTER: { |
| 2107 int input_reg = iterator->Next(); | 2205 int input_reg = iterator->Next(); |
| 2108 intptr_t value = input_->GetRegister(input_reg); | 2206 intptr_t value = input_->GetRegister(input_reg); |
| 2109 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2207 bool is_smi = Smi::IsValid(value); |
| 2110 Smi::IsValid(value); | 2208 if (trace_scope_ != NULL) { |
| 2111 if (trace_) { | |
| 2112 PrintF( | 2209 PrintF( |
| 2210 trace_scope_->file(), |
| 2113 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", | 2211 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", |
| 2114 output_[frame_index]->GetTop() + output_offset, | 2212 output_[frame_index]->GetTop() + output_offset, |
| 2115 output_offset, | 2213 output_offset, |
| 2116 value, | 2214 value, |
| 2117 converter.NameOfCPURegister(input_reg), | 2215 converter.NameOfCPURegister(input_reg), |
| 2118 TraceValueType(is_smi, is_native)); | 2216 TraceValueType(is_smi)); |
| 2119 } | 2217 } |
| 2120 if (is_smi) { | 2218 if (is_smi) { |
| 2121 intptr_t tagged_value = | 2219 intptr_t tagged_value = |
| 2122 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2220 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2123 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2221 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2124 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | |
| 2125 output_[frame_index]->SetFrameSlot(output_offset, value); | |
| 2126 } else { | 2222 } else { |
| 2127 // We save the untagged value on the side and store a GC-safe | 2223 // We save the untagged value on the side and store a GC-safe |
| 2128 // temporary placeholder in the frame. | 2224 // temporary placeholder in the frame. |
| 2129 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | |
| 2130 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2225 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2131 static_cast<double>(static_cast<int32_t>(value))); | 2226 static_cast<double>(static_cast<int32_t>(value))); |
| 2132 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2227 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2133 } | 2228 } |
| 2134 return; | 2229 return; |
| 2135 } | 2230 } |
| 2136 | 2231 |
| 2137 case Translation::UINT32_REGISTER: { | 2232 case Translation::UINT32_REGISTER: { |
| 2138 int input_reg = iterator->Next(); | 2233 int input_reg = iterator->Next(); |
| 2139 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 2234 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); |
| 2140 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2235 bool is_smi = value <= static_cast<uintptr_t>(Smi::kMaxValue); |
| 2141 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2236 if (trace_scope_ != NULL) { |
| 2142 if (trace_) { | |
| 2143 PrintF( | 2237 PrintF( |
| 2238 trace_scope_->file(), |
| 2144 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR | 2239 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR |
| 2145 " ; uint %s (%s)\n", | 2240 " ; uint %s (%s)\n", |
| 2146 output_[frame_index]->GetTop() + output_offset, | 2241 output_[frame_index]->GetTop() + output_offset, |
| 2147 output_offset, | 2242 output_offset, |
| 2148 value, | 2243 value, |
| 2149 converter.NameOfCPURegister(input_reg), | 2244 converter.NameOfCPURegister(input_reg), |
| 2150 TraceValueType(is_smi, is_native)); | 2245 TraceValueType(is_smi)); |
| 2151 } | 2246 } |
| 2152 if (is_smi) { | 2247 if (is_smi) { |
| 2153 intptr_t tagged_value = | 2248 intptr_t tagged_value = |
| 2154 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2249 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2155 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2250 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2156 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | |
| 2157 output_[frame_index]->SetFrameSlot(output_offset, value); | |
| 2158 } else { | 2251 } else { |
| 2159 // We save the untagged value on the side and store a GC-safe | 2252 // We save the untagged value on the side and store a GC-safe |
| 2160 // temporary placeholder in the frame. | 2253 // temporary placeholder in the frame. |
| 2161 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | |
| 2162 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2254 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2163 static_cast<double>(static_cast<uint32_t>(value))); | 2255 static_cast<double>(static_cast<uint32_t>(value))); |
| 2164 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2256 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2165 } | 2257 } |
| 2166 return; | 2258 return; |
| 2167 } | 2259 } |
| 2168 | 2260 |
| 2169 case Translation::DOUBLE_REGISTER: { | 2261 case Translation::DOUBLE_REGISTER: { |
| 2170 int input_reg = iterator->Next(); | 2262 int input_reg = iterator->Next(); |
| 2171 double value = input_->GetDoubleRegister(input_reg); | 2263 double value = input_->GetDoubleRegister(input_reg); |
| 2172 if (trace_) { | 2264 if (trace_scope_ != NULL) { |
| 2173 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", | 2265 PrintF(trace_scope_->file(), |
| 2266 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", |
| 2174 output_[frame_index]->GetTop() + output_offset, | 2267 output_[frame_index]->GetTop() + output_offset, |
| 2175 output_offset, | 2268 output_offset, |
| 2176 value, | 2269 value, |
| 2177 DoubleRegister::AllocationIndexToString(input_reg)); | 2270 DoubleRegister::AllocationIndexToString(input_reg)); |
| 2178 } | 2271 } |
| 2179 // We save the untagged value on the side and store a GC-safe | 2272 // We save the untagged value on the side and store a GC-safe |
| 2180 // temporary placeholder in the frame. | 2273 // temporary placeholder in the frame. |
| 2181 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 2274 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
| 2182 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2275 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2183 return; | 2276 return; |
| 2184 } | 2277 } |
| 2185 | 2278 |
| 2186 case Translation::STACK_SLOT: { | 2279 case Translation::STACK_SLOT: { |
| 2187 int input_slot_index = iterator->Next(); | 2280 int input_slot_index = iterator->Next(); |
| 2188 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2281 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2189 intptr_t input_value = input_->GetFrameSlot(input_offset); | 2282 intptr_t input_value = input_->GetFrameSlot(input_offset); |
| 2190 if (trace_) { | 2283 if (trace_scope_ != NULL) { |
| 2191 PrintF(" 0x%08" V8PRIxPTR ": ", | 2284 PrintF(trace_scope_->file(), |
| 2285 " 0x%08" V8PRIxPTR ": ", |
| 2192 output_[frame_index]->GetTop() + output_offset); | 2286 output_[frame_index]->GetTop() + output_offset); |
| 2193 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", | 2287 PrintF(trace_scope_->file(), |
| 2288 "[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", |
| 2194 output_offset, | 2289 output_offset, |
| 2195 input_value, | 2290 input_value, |
| 2196 input_offset); | 2291 input_offset); |
| 2197 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2292 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2198 PrintF("\n"); | 2293 trace_scope_->file()); |
| 2294 PrintF(trace_scope_->file(), "\n"); |
| 2199 } | 2295 } |
| 2200 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 2296 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
| 2201 return; | 2297 return; |
| 2202 } | 2298 } |
| 2203 | 2299 |
| 2204 case Translation::INT32_STACK_SLOT: { | 2300 case Translation::INT32_STACK_SLOT: { |
| 2205 int input_slot_index = iterator->Next(); | 2301 int input_slot_index = iterator->Next(); |
| 2206 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2302 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2207 intptr_t value = input_->GetFrameSlot(input_offset); | 2303 intptr_t value = input_->GetFrameSlot(input_offset); |
| 2208 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2304 bool is_smi = Smi::IsValid(value); |
| 2209 Smi::IsValid(value); | 2305 if (trace_scope_ != NULL) { |
| 2210 if (trace_) { | 2306 PrintF(trace_scope_->file(), |
| 2211 PrintF(" 0x%08" V8PRIxPTR ": ", | 2307 " 0x%08" V8PRIxPTR ": ", |
| 2212 output_[frame_index]->GetTop() + output_offset); | 2308 output_[frame_index]->GetTop() + output_offset); |
| 2213 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", | 2309 PrintF(trace_scope_->file(), |
| 2310 "[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", |
| 2214 output_offset, | 2311 output_offset, |
| 2215 value, | 2312 value, |
| 2216 input_offset, | 2313 input_offset, |
| 2217 TraceValueType(is_smi, is_native)); | 2314 TraceValueType(is_smi)); |
| 2218 } | 2315 } |
| 2219 if (is_smi) { | 2316 if (is_smi) { |
| 2220 intptr_t tagged_value = | 2317 intptr_t tagged_value = |
| 2221 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2318 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2222 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2319 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2223 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | |
| 2224 output_[frame_index]->SetFrameSlot(output_offset, value); | |
| 2225 } else { | 2320 } else { |
| 2226 // We save the untagged value on the side and store a GC-safe | 2321 // We save the untagged value on the side and store a GC-safe |
| 2227 // temporary placeholder in the frame. | 2322 // temporary placeholder in the frame. |
| 2228 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | |
| 2229 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2323 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2230 static_cast<double>(static_cast<int32_t>(value))); | 2324 static_cast<double>(static_cast<int32_t>(value))); |
| 2231 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2325 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2232 } | 2326 } |
| 2233 return; | 2327 return; |
| 2234 } | 2328 } |
| 2235 | 2329 |
| 2236 case Translation::UINT32_STACK_SLOT: { | 2330 case Translation::UINT32_STACK_SLOT: { |
| 2237 int input_slot_index = iterator->Next(); | 2331 int input_slot_index = iterator->Next(); |
| 2238 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2332 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2239 uintptr_t value = | 2333 uintptr_t value = |
| 2240 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 2334 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
| 2241 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2335 bool is_smi = value <= static_cast<uintptr_t>(Smi::kMaxValue); |
| 2242 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2336 if (trace_scope_ != NULL) { |
| 2243 if (trace_) { | 2337 PrintF(trace_scope_->file(), |
| 2244 PrintF(" 0x%08" V8PRIxPTR ": ", | 2338 " 0x%08" V8PRIxPTR ": ", |
| 2245 output_[frame_index]->GetTop() + output_offset); | 2339 output_[frame_index]->GetTop() + output_offset); |
| 2246 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", | 2340 PrintF(trace_scope_->file(), |
| 2341 "[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", |
| 2247 output_offset, | 2342 output_offset, |
| 2248 value, | 2343 value, |
| 2249 input_offset, | 2344 input_offset, |
| 2250 TraceValueType(is_smi, is_native)); | 2345 TraceValueType(is_smi)); |
| 2251 } | 2346 } |
| 2252 if (is_smi) { | 2347 if (is_smi) { |
| 2253 intptr_t tagged_value = | 2348 intptr_t tagged_value = |
| 2254 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2349 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2255 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2350 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2256 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | |
| 2257 output_[frame_index]->SetFrameSlot(output_offset, value); | |
| 2258 } else { | 2351 } else { |
| 2259 // We save the untagged value on the side and store a GC-safe | 2352 // We save the untagged value on the side and store a GC-safe |
| 2260 // temporary placeholder in the frame. | 2353 // temporary placeholder in the frame. |
| 2261 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | |
| 2262 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2354 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2263 static_cast<double>(static_cast<uint32_t>(value))); | 2355 static_cast<double>(static_cast<uint32_t>(value))); |
| 2264 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2356 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2265 } | 2357 } |
| 2266 return; | 2358 return; |
| 2267 } | 2359 } |
| 2268 | 2360 |
| 2269 case Translation::DOUBLE_STACK_SLOT: { | 2361 case Translation::DOUBLE_STACK_SLOT: { |
| 2270 int input_slot_index = iterator->Next(); | 2362 int input_slot_index = iterator->Next(); |
| 2271 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2363 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2272 double value = input_->GetDoubleFrameSlot(input_offset); | 2364 double value = input_->GetDoubleFrameSlot(input_offset); |
| 2273 if (trace_) { | 2365 if (trace_scope_ != NULL) { |
| 2274 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", | 2366 PrintF(trace_scope_->file(), |
| 2367 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", |
| 2275 output_[frame_index]->GetTop() + output_offset, | 2368 output_[frame_index]->GetTop() + output_offset, |
| 2276 output_offset, | 2369 output_offset, |
| 2277 value, | 2370 value, |
| 2278 input_offset); | 2371 input_offset); |
| 2279 } | 2372 } |
| 2280 // We save the untagged value on the side and store a GC-safe | 2373 // We save the untagged value on the side and store a GC-safe |
| 2281 // temporary placeholder in the frame. | 2374 // temporary placeholder in the frame. |
| 2282 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 2375 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
| 2283 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2376 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2284 return; | 2377 return; |
| 2285 } | 2378 } |
| 2286 | 2379 |
| 2287 case Translation::LITERAL: { | 2380 case Translation::LITERAL: { |
| 2288 Object* literal = ComputeLiteral(iterator->Next()); | 2381 Object* literal = ComputeLiteral(iterator->Next()); |
| 2289 if (trace_) { | 2382 if (trace_scope_ != NULL) { |
| 2290 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2383 PrintF(trace_scope_->file(), |
| 2384 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2291 output_[frame_index]->GetTop() + output_offset, | 2385 output_[frame_index]->GetTop() + output_offset, |
| 2292 output_offset); | 2386 output_offset); |
| 2293 literal->ShortPrint(); | 2387 literal->ShortPrint(trace_scope_->file()); |
| 2294 PrintF(" ; literal\n"); | 2388 PrintF(trace_scope_->file(), " ; literal\n"); |
| 2295 } | 2389 } |
| 2296 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2390 intptr_t value = reinterpret_cast<intptr_t>(literal); |
| 2297 output_[frame_index]->SetFrameSlot(output_offset, value); | 2391 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2298 return; | 2392 return; |
| 2299 } | 2393 } |
| 2300 | 2394 |
| 2301 case Translation::DUPLICATED_OBJECT: { | 2395 case Translation::DUPLICATED_OBJECT: { |
| 2302 int object_index = iterator->Next(); | 2396 int object_index = iterator->Next(); |
| 2303 if (trace_) { | 2397 if (trace_scope_ != NULL) { |
| 2304 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2398 PrintF(trace_scope_->file(), |
| 2399 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2305 output_[frame_index]->GetTop() + output_offset, | 2400 output_[frame_index]->GetTop() + output_offset, |
| 2306 output_offset); | 2401 output_offset); |
| 2307 isolate_->heap()->arguments_marker()->ShortPrint(); | 2402 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2308 PrintF(" ; duplicate of object #%d\n", object_index); | 2403 PrintF(trace_scope_->file(), |
| 2404 " ; duplicate of object #%d\n", object_index); |
| 2309 } | 2405 } |
| 2310 // Use the materialization marker value as a sentinel and fill in | 2406 // Use the materialization marker value as a sentinel and fill in |
| 2311 // the object after the deoptimized frame is built. | 2407 // the object after the deoptimized frame is built. |
| 2312 intptr_t value = reinterpret_cast<intptr_t>( | 2408 intptr_t value = reinterpret_cast<intptr_t>( |
| 2313 isolate_->heap()->arguments_marker()); | 2409 isolate_->heap()->arguments_marker()); |
| 2314 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, | 2410 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, |
| 2315 object_index); | 2411 object_index); |
| 2316 output_[frame_index]->SetFrameSlot(output_offset, value); | 2412 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2317 return; | 2413 return; |
| 2318 } | 2414 } |
| 2319 | 2415 |
| 2320 case Translation::ARGUMENTS_OBJECT: | 2416 case Translation::ARGUMENTS_OBJECT: |
| 2321 case Translation::CAPTURED_OBJECT: { | 2417 case Translation::CAPTURED_OBJECT: { |
| 2322 int length = iterator->Next(); | 2418 int length = iterator->Next(); |
| 2323 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; | 2419 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2324 if (trace_) { | 2420 if (trace_scope_ != NULL) { |
| 2325 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2421 PrintF(trace_scope_->file(), |
| 2422 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2326 output_[frame_index]->GetTop() + output_offset, | 2423 output_[frame_index]->GetTop() + output_offset, |
| 2327 output_offset); | 2424 output_offset); |
| 2328 isolate_->heap()->arguments_marker()->ShortPrint(); | 2425 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2329 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); | 2426 PrintF(trace_scope_->file(), |
| 2427 " ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2330 } | 2428 } |
| 2331 // Use the materialization marker value as a sentinel and fill in | 2429 // Use the materialization marker value as a sentinel and fill in |
| 2332 // the object after the deoptimized frame is built. | 2430 // the object after the deoptimized frame is built. |
| 2333 intptr_t value = reinterpret_cast<intptr_t>( | 2431 intptr_t value = reinterpret_cast<intptr_t>( |
| 2334 isolate_->heap()->arguments_marker()); | 2432 isolate_->heap()->arguments_marker()); |
| 2335 AddObjectStart(output_[frame_index]->GetTop() + output_offset, | 2433 AddObjectStart(output_[frame_index]->GetTop() + output_offset, |
| 2336 length, is_args); | 2434 length, is_args); |
| 2337 output_[frame_index]->SetFrameSlot(output_offset, value); | 2435 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2338 // We save the object values on the side and materialize the actual | 2436 // We save the object values on the side and materialize the actual |
| 2339 // object after the deoptimized frame is built. | 2437 // object after the deoptimized frame is built. |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2948 | 3046 |
| 2949 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3047 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 2950 v->VisitPointer(BitCast<Object**>(&function_)); | 3048 v->VisitPointer(BitCast<Object**>(&function_)); |
| 2951 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3049 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 2952 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3050 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 2953 } | 3051 } |
| 2954 | 3052 |
| 2955 #endif // ENABLE_DEBUGGER_SUPPORT | 3053 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2956 | 3054 |
| 2957 } } // namespace v8::internal | 3055 } } // namespace v8::internal |
| OLD | NEW |