| 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. |
| 1541 for (int i = 0; i < descriptor->register_param_count_; ++i) { | 1589 for (int i = 0; i < descriptor->register_param_count_; ++i) { |
| 1542 output_frame_offset -= kPointerSize; | 1590 output_frame_offset -= kPointerSize; |
| 1543 DoTranslateCommand(iterator, 0, output_frame_offset); | 1591 DoTranslateCommand(iterator, 0, output_frame_offset); |
| 1544 } | 1592 } |
| 1545 | 1593 |
| 1546 if (!arg_count_known) { | 1594 if (!arg_count_known) { |
| 1547 DoTranslateCommand(iterator, 0, length_frame_offset, | 1595 DoTranslateCommand(iterator, 0, length_frame_offset, |
| 1548 TRANSLATED_VALUE_IS_NATIVE); | 1596 TRANSLATED_VALUE_IS_NATIVE); |
| 1549 caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); | 1597 caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); |
| 1550 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 1598 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + |
| 1551 (caller_arg_count - 1) * kPointerSize; | 1599 (caller_arg_count - 1) * kPointerSize; |
| 1552 output_frame->SetFrameSlot(args_arguments_offset, value); | 1600 output_frame->SetFrameSlot(args_arguments_offset, value); |
| 1553 if (trace_) { | 1601 if (trace_scope_ != NULL) { |
| 1554 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1602 PrintF(trace_scope_->file(), |
| 1603 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1555 V8PRIxPTR " ; args.arguments\n", | 1604 V8PRIxPTR " ; args.arguments\n", |
| 1556 top_address + args_arguments_offset, args_arguments_offset, value); | 1605 top_address + args_arguments_offset, args_arguments_offset, value); |
| 1557 } | 1606 } |
| 1558 } | 1607 } |
| 1559 | 1608 |
| 1560 ASSERT(0 == output_frame_offset); | 1609 ASSERT(0 == output_frame_offset); |
| 1561 | 1610 |
| 1562 // Copy the double registers from the input into the output frame. | 1611 // Copy the double registers from the input into the output frame. |
| 1563 CopyDoubleRegisters(output_frame); | 1612 CopyDoubleRegisters(output_frame); |
| 1564 | 1613 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 materialized_objects_->Add(object); | 1693 materialized_objects_->Add(object); |
| 1645 Handle<Object> properties = MaterializeNextValue(); | 1694 Handle<Object> properties = MaterializeNextValue(); |
| 1646 Handle<Object> elements = MaterializeNextValue(); | 1695 Handle<Object> elements = MaterializeNextValue(); |
| 1647 Handle<Object> length = MaterializeNextValue(); | 1696 Handle<Object> length = MaterializeNextValue(); |
| 1648 object->set_properties(FixedArray::cast(*properties)); | 1697 object->set_properties(FixedArray::cast(*properties)); |
| 1649 object->set_elements(FixedArrayBase::cast(*elements)); | 1698 object->set_elements(FixedArrayBase::cast(*elements)); |
| 1650 object->set_length(*length); | 1699 object->set_length(*length); |
| 1651 break; | 1700 break; |
| 1652 } | 1701 } |
| 1653 default: | 1702 default: |
| 1654 PrintF("[couldn't handle instance type %d]\n", map->instance_type()); | 1703 PrintF(stderr, |
| 1704 "[couldn't handle instance type %d]\n", map->instance_type()); |
| 1655 UNREACHABLE(); | 1705 UNREACHABLE(); |
| 1656 } | 1706 } |
| 1657 } | 1707 } |
| 1658 | 1708 |
| 1659 return materialized_objects_->at(object_index); | 1709 return materialized_objects_->at(object_index); |
| 1660 } | 1710 } |
| 1661 | 1711 |
| 1662 | 1712 |
| 1663 Handle<Object> Deoptimizer::MaterializeNextValue() { | 1713 Handle<Object> Deoptimizer::MaterializeNextValue() { |
| 1664 int value_index = materialization_value_index_++; | 1714 int value_index = materialization_value_index_++; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1689 | 1739 |
| 1690 // Play it safe and clear all unhandlified values before we continue. | 1740 // Play it safe and clear all unhandlified values before we continue. |
| 1691 deferred_objects_tagged_values_.Clear(); | 1741 deferred_objects_tagged_values_.Clear(); |
| 1692 | 1742 |
| 1693 // Materialize all heap numbers before looking at arguments because when the | 1743 // Materialize all heap numbers before looking at arguments because when the |
| 1694 // output frames are used to materialize arguments objects later on they need | 1744 // output frames are used to materialize arguments objects later on they need |
| 1695 // to already contain valid heap numbers. | 1745 // to already contain valid heap numbers. |
| 1696 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { | 1746 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { |
| 1697 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; | 1747 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; |
| 1698 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1748 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1699 if (trace_) { | 1749 if (trace_scope_ != NULL) { |
| 1700 PrintF("Materialized a new heap number %p [%e] in slot %p\n", | 1750 PrintF(trace_scope_->file(), |
| 1751 "Materialized a new heap number %p [%e] in slot %p\n", |
| 1701 reinterpret_cast<void*>(*num), | 1752 reinterpret_cast<void*>(*num), |
| 1702 d.value(), | 1753 d.value(), |
| 1703 d.destination()); | 1754 d.destination()); |
| 1704 } | 1755 } |
| 1705 Memory::Object_at(d.destination()) = *num; | 1756 Memory::Object_at(d.destination()) = *num; |
| 1706 } | 1757 } |
| 1707 | 1758 |
| 1708 // Materialize all heap numbers required for arguments/captured objects. | 1759 // Materialize all heap numbers required for arguments/captured objects. |
| 1709 for (int i = 0; i < deferred_objects_double_values_.length(); i++) { | 1760 for (int i = 0; i < deferred_objects_double_values_.length(); i++) { |
| 1710 HeapNumberMaterializationDescriptor<int> d = | 1761 HeapNumberMaterializationDescriptor<int> d = |
| 1711 deferred_objects_double_values_[i]; | 1762 deferred_objects_double_values_[i]; |
| 1712 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1763 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1713 if (trace_) { | 1764 if (trace_scope_ != NULL) { |
| 1714 PrintF("Materialized a new heap number %p [%e] for object at %d\n", | 1765 PrintF(trace_scope_->file(), |
| 1766 "Materialized a new heap number %p [%e] for object at %d\n", |
| 1715 reinterpret_cast<void*>(*num), | 1767 reinterpret_cast<void*>(*num), |
| 1716 d.value(), | 1768 d.value(), |
| 1717 d.destination()); | 1769 d.destination()); |
| 1718 } | 1770 } |
| 1719 ASSERT(values.at(d.destination())->IsTheHole()); | 1771 ASSERT(values.at(d.destination())->IsTheHole()); |
| 1720 values.Set(d.destination(), num); | 1772 values.Set(d.destination(), num); |
| 1721 } | 1773 } |
| 1722 | 1774 |
| 1723 // Play it safe and clear all object double values before we continue. | 1775 // Play it safe and clear all object double values before we continue. |
| 1724 deferred_objects_double_values_.Clear(); | 1776 deferred_objects_double_values_.Clear(); |
| 1725 | 1777 |
| 1726 // Materialize arguments/captured objects. | 1778 // Materialize arguments/captured objects. |
| 1727 if (!deferred_objects_.is_empty()) { | 1779 if (!deferred_objects_.is_empty()) { |
| 1728 List<Handle<Object> > materialized_objects(deferred_objects_.length()); | 1780 List<Handle<Object> > materialized_objects(deferred_objects_.length()); |
| 1729 materialized_objects_ = &materialized_objects; | 1781 materialized_objects_ = &materialized_objects; |
| 1730 materialized_values_ = &values; | 1782 materialized_values_ = &values; |
| 1731 | 1783 |
| 1732 while (materialization_object_index_ < deferred_objects_.length()) { | 1784 while (materialization_object_index_ < deferred_objects_.length()) { |
| 1733 int object_index = materialization_object_index_; | 1785 int object_index = materialization_object_index_; |
| 1734 ObjectMaterializationDescriptor descriptor = | 1786 ObjectMaterializationDescriptor descriptor = |
| 1735 deferred_objects_.at(object_index); | 1787 deferred_objects_.at(object_index); |
| 1736 | 1788 |
| 1737 // Find a previously materialized object by de-duplication or | 1789 // Find a previously materialized object by de-duplication or |
| 1738 // materialize a new instance of the object if necessary. Store | 1790 // materialize a new instance of the object if necessary. Store |
| 1739 // the materialized object into the frame slot. | 1791 // the materialized object into the frame slot. |
| 1740 Handle<Object> object = MaterializeNextHeapObject(); | 1792 Handle<Object> object = MaterializeNextHeapObject(); |
| 1741 Memory::Object_at(descriptor.slot_address()) = *object; | 1793 Memory::Object_at(descriptor.slot_address()) = *object; |
| 1742 if (trace_) { | 1794 if (trace_scope_ != NULL) { |
| 1743 if (descriptor.is_arguments()) { | 1795 if (descriptor.is_arguments()) { |
| 1744 PrintF("Materialized %sarguments object of length %d for %p: ", | 1796 PrintF(trace_scope_->file(), |
| 1797 "Materialized %sarguments object of length %d for %p: ", |
| 1745 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", | 1798 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", |
| 1746 Handle<JSObject>::cast(object)->elements()->length(), | 1799 Handle<JSObject>::cast(object)->elements()->length(), |
| 1747 reinterpret_cast<void*>(descriptor.slot_address())); | 1800 reinterpret_cast<void*>(descriptor.slot_address())); |
| 1748 } else { | 1801 } else { |
| 1749 PrintF("Materialized captured object of size %d for %p: ", | 1802 PrintF(trace_scope_->file(), |
| 1803 "Materialized captured object of size %d for %p: ", |
| 1750 Handle<HeapObject>::cast(object)->Size(), | 1804 Handle<HeapObject>::cast(object)->Size(), |
| 1751 reinterpret_cast<void*>(descriptor.slot_address())); | 1805 reinterpret_cast<void*>(descriptor.slot_address())); |
| 1752 } | 1806 } |
| 1753 object->ShortPrint(); | 1807 object->ShortPrint(trace_scope_->file()); |
| 1754 PrintF("\n"); | 1808 PrintF(trace_scope_->file(), "\n"); |
| 1755 } | 1809 } |
| 1756 } | 1810 } |
| 1757 | 1811 |
| 1758 ASSERT(materialization_object_index_ == materialized_objects_->length()); | 1812 ASSERT(materialization_object_index_ == materialized_objects_->length()); |
| 1759 ASSERT(materialization_value_index_ == materialized_values_->length()); | 1813 ASSERT(materialization_value_index_ == materialized_values_->length()); |
| 1760 } | 1814 } |
| 1761 } | 1815 } |
| 1762 | 1816 |
| 1763 | 1817 |
| 1764 #ifdef ENABLE_DEBUGGER_SUPPORT | 1818 #ifdef ENABLE_DEBUGGER_SUPPORT |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1776 | 1830 |
| 1777 // Check of the heap number to materialize actually belong to the frame | 1831 // Check of the heap number to materialize actually belong to the frame |
| 1778 // being extracted. | 1832 // being extracted. |
| 1779 Address slot = d.destination(); | 1833 Address slot = d.destination(); |
| 1780 if (parameters_top <= slot && slot < parameters_bottom) { | 1834 if (parameters_top <= slot && slot < parameters_bottom) { |
| 1781 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1835 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1782 | 1836 |
| 1783 int index = (info->parameters_count() - 1) - | 1837 int index = (info->parameters_count() - 1) - |
| 1784 static_cast<int>(slot - parameters_top) / kPointerSize; | 1838 static_cast<int>(slot - parameters_top) / kPointerSize; |
| 1785 | 1839 |
| 1786 if (trace_) { | 1840 if (trace_scope_ != NULL) { |
| 1787 PrintF("Materializing a new heap number %p [%e] in slot %p" | 1841 PrintF(trace_scope_->file(), |
| 1842 "Materializing a new heap number %p [%e] in slot %p" |
| 1788 "for parameter slot #%d\n", | 1843 "for parameter slot #%d\n", |
| 1789 reinterpret_cast<void*>(*num), | 1844 reinterpret_cast<void*>(*num), |
| 1790 d.value(), | 1845 d.value(), |
| 1791 d.destination(), | 1846 d.destination(), |
| 1792 index); | 1847 index); |
| 1793 } | 1848 } |
| 1794 | 1849 |
| 1795 info->SetParameter(index, *num); | 1850 info->SetParameter(index, *num); |
| 1796 } else if (expressions_top <= slot && slot < expressions_bottom) { | 1851 } else if (expressions_top <= slot && slot < expressions_bottom) { |
| 1797 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 1852 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
| 1798 | 1853 |
| 1799 int index = info->expression_count() - 1 - | 1854 int index = info->expression_count() - 1 - |
| 1800 static_cast<int>(slot - expressions_top) / kPointerSize; | 1855 static_cast<int>(slot - expressions_top) / kPointerSize; |
| 1801 | 1856 |
| 1802 if (trace_) { | 1857 if (trace_scope_ != NULL) { |
| 1803 PrintF("Materializing a new heap number %p [%e] in slot %p" | 1858 PrintF(trace_scope_->file(), |
| 1859 "Materializing a new heap number %p [%e] in slot %p" |
| 1804 "for expression slot #%d\n", | 1860 "for expression slot #%d\n", |
| 1805 reinterpret_cast<void*>(*num), | 1861 reinterpret_cast<void*>(*num), |
| 1806 d.value(), | 1862 d.value(), |
| 1807 d.destination(), | 1863 d.destination(), |
| 1808 index); | 1864 index); |
| 1809 } | 1865 } |
| 1810 | 1866 |
| 1811 info->SetExpression(index, *num); | 1867 info->SetExpression(index, *num); |
| 1812 } | 1868 } |
| 1813 } | 1869 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1842 case Translation::CONSTRUCT_STUB_FRAME: | 1898 case Translation::CONSTRUCT_STUB_FRAME: |
| 1843 case Translation::GETTER_STUB_FRAME: | 1899 case Translation::GETTER_STUB_FRAME: |
| 1844 case Translation::SETTER_STUB_FRAME: | 1900 case Translation::SETTER_STUB_FRAME: |
| 1845 case Translation::COMPILED_STUB_FRAME: | 1901 case Translation::COMPILED_STUB_FRAME: |
| 1846 UNREACHABLE(); | 1902 UNREACHABLE(); |
| 1847 return; | 1903 return; |
| 1848 | 1904 |
| 1849 case Translation::REGISTER: { | 1905 case Translation::REGISTER: { |
| 1850 int input_reg = iterator->Next(); | 1906 int input_reg = iterator->Next(); |
| 1851 intptr_t input_value = input_->GetRegister(input_reg); | 1907 intptr_t input_value = input_->GetRegister(input_reg); |
| 1852 if (trace_) { | 1908 if (trace_scope_ != NULL) { |
| 1853 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1909 PrintF(trace_scope_->file(), |
| 1910 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1854 reinterpret_cast<intptr_t>(object_slot), | 1911 reinterpret_cast<intptr_t>(object_slot), |
| 1855 field_index); | 1912 field_index); |
| 1856 PrintF("0x%08" V8PRIxPTR " ; %s ", input_value, | 1913 PrintF(trace_scope_->file(), |
| 1914 "0x%08" V8PRIxPTR " ; %s ", input_value, |
| 1857 converter.NameOfCPURegister(input_reg)); | 1915 converter.NameOfCPURegister(input_reg)); |
| 1858 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 1916 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 1859 PrintF("\n"); | 1917 trace_scope_->file()); |
| 1918 PrintF(trace_scope_->file(), |
| 1919 "\n"); |
| 1860 } | 1920 } |
| 1861 AddObjectTaggedValue(input_value); | 1921 AddObjectTaggedValue(input_value); |
| 1862 return; | 1922 return; |
| 1863 } | 1923 } |
| 1864 | 1924 |
| 1865 case Translation::INT32_REGISTER: { | 1925 case Translation::INT32_REGISTER: { |
| 1866 int input_reg = iterator->Next(); | 1926 int input_reg = iterator->Next(); |
| 1867 intptr_t value = input_->GetRegister(input_reg); | 1927 intptr_t value = input_->GetRegister(input_reg); |
| 1868 bool is_smi = Smi::IsValid(value); | 1928 bool is_smi = Smi::IsValid(value); |
| 1869 if (trace_) { | 1929 if (trace_scope_ != NULL) { |
| 1870 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1930 PrintF(trace_scope_->file(), |
| 1931 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1871 reinterpret_cast<intptr_t>(object_slot), | 1932 reinterpret_cast<intptr_t>(object_slot), |
| 1872 field_index); | 1933 field_index); |
| 1873 PrintF("%" V8PRIdPTR " ; %s (%s)\n", value, | 1934 PrintF(trace_scope_->file(), |
| 1935 "%" V8PRIdPTR " ; %s (%s)\n", value, |
| 1874 converter.NameOfCPURegister(input_reg), | 1936 converter.NameOfCPURegister(input_reg), |
| 1875 TraceValueType(is_smi)); | 1937 TraceValueType(is_smi)); |
| 1876 } | 1938 } |
| 1877 if (is_smi) { | 1939 if (is_smi) { |
| 1878 intptr_t tagged_value = | 1940 intptr_t tagged_value = |
| 1879 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1941 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1880 AddObjectTaggedValue(tagged_value); | 1942 AddObjectTaggedValue(tagged_value); |
| 1881 } else { | 1943 } else { |
| 1882 double double_value = static_cast<double>(static_cast<int32_t>(value)); | 1944 double double_value = static_cast<double>(static_cast<int32_t>(value)); |
| 1883 AddObjectDoubleValue(double_value); | 1945 AddObjectDoubleValue(double_value); |
| 1884 } | 1946 } |
| 1885 return; | 1947 return; |
| 1886 } | 1948 } |
| 1887 | 1949 |
| 1888 case Translation::UINT32_REGISTER: { | 1950 case Translation::UINT32_REGISTER: { |
| 1889 int input_reg = iterator->Next(); | 1951 int input_reg = iterator->Next(); |
| 1890 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 1952 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); |
| 1891 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 1953 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 1892 if (trace_) { | 1954 if (trace_scope_ != NULL) { |
| 1893 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1955 PrintF(trace_scope_->file(), |
| 1956 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1894 reinterpret_cast<intptr_t>(object_slot), | 1957 reinterpret_cast<intptr_t>(object_slot), |
| 1895 field_index); | 1958 field_index); |
| 1896 PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value, | 1959 PrintF(trace_scope_->file(), |
| 1960 "%" V8PRIdPTR " ; uint %s (%s)\n", value, |
| 1897 converter.NameOfCPURegister(input_reg), | 1961 converter.NameOfCPURegister(input_reg), |
| 1898 TraceValueType(is_smi)); | 1962 TraceValueType(is_smi)); |
| 1899 } | 1963 } |
| 1900 if (is_smi) { | 1964 if (is_smi) { |
| 1901 intptr_t tagged_value = | 1965 intptr_t tagged_value = |
| 1902 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1966 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1903 AddObjectTaggedValue(tagged_value); | 1967 AddObjectTaggedValue(tagged_value); |
| 1904 } else { | 1968 } else { |
| 1905 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | 1969 double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
| 1906 AddObjectDoubleValue(double_value); | 1970 AddObjectDoubleValue(double_value); |
| 1907 } | 1971 } |
| 1908 return; | 1972 return; |
| 1909 } | 1973 } |
| 1910 | 1974 |
| 1911 case Translation::DOUBLE_REGISTER: { | 1975 case Translation::DOUBLE_REGISTER: { |
| 1912 int input_reg = iterator->Next(); | 1976 int input_reg = iterator->Next(); |
| 1913 double value = input_->GetDoubleRegister(input_reg); | 1977 double value = input_->GetDoubleRegister(input_reg); |
| 1914 if (trace_) { | 1978 if (trace_scope_ != NULL) { |
| 1915 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1979 PrintF(trace_scope_->file(), |
| 1980 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1916 reinterpret_cast<intptr_t>(object_slot), | 1981 reinterpret_cast<intptr_t>(object_slot), |
| 1917 field_index); | 1982 field_index); |
| 1918 PrintF("%e ; %s\n", value, | 1983 PrintF(trace_scope_->file(), |
| 1984 "%e ; %s\n", value, |
| 1919 DoubleRegister::AllocationIndexToString(input_reg)); | 1985 DoubleRegister::AllocationIndexToString(input_reg)); |
| 1920 } | 1986 } |
| 1921 AddObjectDoubleValue(value); | 1987 AddObjectDoubleValue(value); |
| 1922 return; | 1988 return; |
| 1923 } | 1989 } |
| 1924 | 1990 |
| 1925 case Translation::STACK_SLOT: { | 1991 case Translation::STACK_SLOT: { |
| 1926 int input_slot_index = iterator->Next(); | 1992 int input_slot_index = iterator->Next(); |
| 1927 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 1993 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1928 intptr_t input_value = input_->GetFrameSlot(input_offset); | 1994 intptr_t input_value = input_->GetFrameSlot(input_offset); |
| 1929 if (trace_) { | 1995 if (trace_scope_ != NULL) { |
| 1930 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1996 PrintF(trace_scope_->file(), |
| 1997 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1931 reinterpret_cast<intptr_t>(object_slot), | 1998 reinterpret_cast<intptr_t>(object_slot), |
| 1932 field_index); | 1999 field_index); |
| 1933 PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); | 2000 PrintF(trace_scope_->file(), |
| 1934 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2001 "0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); |
| 1935 PrintF("\n"); | 2002 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2003 trace_scope_->file()); |
| 2004 PrintF(trace_scope_->file(), |
| 2005 "\n"); |
| 1936 } | 2006 } |
| 1937 AddObjectTaggedValue(input_value); | 2007 AddObjectTaggedValue(input_value); |
| 1938 return; | 2008 return; |
| 1939 } | 2009 } |
| 1940 | 2010 |
| 1941 case Translation::INT32_STACK_SLOT: { | 2011 case Translation::INT32_STACK_SLOT: { |
| 1942 int input_slot_index = iterator->Next(); | 2012 int input_slot_index = iterator->Next(); |
| 1943 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2013 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1944 intptr_t value = input_->GetFrameSlot(input_offset); | 2014 intptr_t value = input_->GetFrameSlot(input_offset); |
| 1945 bool is_smi = Smi::IsValid(value); | 2015 bool is_smi = Smi::IsValid(value); |
| 1946 if (trace_) { | 2016 if (trace_scope_ != NULL) { |
| 1947 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2017 PrintF(trace_scope_->file(), |
| 2018 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1948 reinterpret_cast<intptr_t>(object_slot), | 2019 reinterpret_cast<intptr_t>(object_slot), |
| 1949 field_index); | 2020 field_index); |
| 1950 PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n", | 2021 PrintF(trace_scope_->file(), |
| 2022 "%" V8PRIdPTR " ; [sp + %d] (%s)\n", |
| 1951 value, input_offset, TraceValueType(is_smi)); | 2023 value, input_offset, TraceValueType(is_smi)); |
| 1952 } | 2024 } |
| 1953 if (is_smi) { | 2025 if (is_smi) { |
| 1954 intptr_t tagged_value = | 2026 intptr_t tagged_value = |
| 1955 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2027 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1956 AddObjectTaggedValue(tagged_value); | 2028 AddObjectTaggedValue(tagged_value); |
| 1957 } else { | 2029 } else { |
| 1958 double double_value = static_cast<double>(static_cast<int32_t>(value)); | 2030 double double_value = static_cast<double>(static_cast<int32_t>(value)); |
| 1959 AddObjectDoubleValue(double_value); | 2031 AddObjectDoubleValue(double_value); |
| 1960 } | 2032 } |
| 1961 return; | 2033 return; |
| 1962 } | 2034 } |
| 1963 | 2035 |
| 1964 case Translation::UINT32_STACK_SLOT: { | 2036 case Translation::UINT32_STACK_SLOT: { |
| 1965 int input_slot_index = iterator->Next(); | 2037 int input_slot_index = iterator->Next(); |
| 1966 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2038 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1967 uintptr_t value = | 2039 uintptr_t value = |
| 1968 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 2040 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
| 1969 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2041 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 1970 if (trace_) { | 2042 if (trace_scope_ != NULL) { |
| 1971 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2043 PrintF(trace_scope_->file(), |
| 2044 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1972 reinterpret_cast<intptr_t>(object_slot), | 2045 reinterpret_cast<intptr_t>(object_slot), |
| 1973 field_index); | 2046 field_index); |
| 1974 PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", | 2047 PrintF(trace_scope_->file(), |
| 2048 "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", |
| 1975 value, input_offset, TraceValueType(is_smi)); | 2049 value, input_offset, TraceValueType(is_smi)); |
| 1976 } | 2050 } |
| 1977 if (is_smi) { | 2051 if (is_smi) { |
| 1978 intptr_t tagged_value = | 2052 intptr_t tagged_value = |
| 1979 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2053 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 1980 AddObjectTaggedValue(tagged_value); | 2054 AddObjectTaggedValue(tagged_value); |
| 1981 } else { | 2055 } else { |
| 1982 double double_value = static_cast<double>(static_cast<uint32_t>(value)); | 2056 double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
| 1983 AddObjectDoubleValue(double_value); | 2057 AddObjectDoubleValue(double_value); |
| 1984 } | 2058 } |
| 1985 return; | 2059 return; |
| 1986 } | 2060 } |
| 1987 | 2061 |
| 1988 case Translation::DOUBLE_STACK_SLOT: { | 2062 case Translation::DOUBLE_STACK_SLOT: { |
| 1989 int input_slot_index = iterator->Next(); | 2063 int input_slot_index = iterator->Next(); |
| 1990 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2064 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 1991 double value = input_->GetDoubleFrameSlot(input_offset); | 2065 double value = input_->GetDoubleFrameSlot(input_offset); |
| 1992 if (trace_) { | 2066 if (trace_scope_ != NULL) { |
| 1993 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2067 PrintF(trace_scope_->file(), |
| 2068 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1994 reinterpret_cast<intptr_t>(object_slot), | 2069 reinterpret_cast<intptr_t>(object_slot), |
| 1995 field_index); | 2070 field_index); |
| 1996 PrintF("%e ; [sp + %d]\n", value, input_offset); | 2071 PrintF(trace_scope_->file(), |
| 2072 "%e ; [sp + %d]\n", value, input_offset); |
| 1997 } | 2073 } |
| 1998 AddObjectDoubleValue(value); | 2074 AddObjectDoubleValue(value); |
| 1999 return; | 2075 return; |
| 2000 } | 2076 } |
| 2001 | 2077 |
| 2002 case Translation::LITERAL: { | 2078 case Translation::LITERAL: { |
| 2003 Object* literal = ComputeLiteral(iterator->Next()); | 2079 Object* literal = ComputeLiteral(iterator->Next()); |
| 2004 if (trace_) { | 2080 if (trace_scope_ != NULL) { |
| 2005 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2081 PrintF(trace_scope_->file(), |
| 2082 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2006 reinterpret_cast<intptr_t>(object_slot), | 2083 reinterpret_cast<intptr_t>(object_slot), |
| 2007 field_index); | 2084 field_index); |
| 2008 literal->ShortPrint(); | 2085 literal->ShortPrint(trace_scope_->file()); |
| 2009 PrintF(" ; literal\n"); | 2086 PrintF(trace_scope_->file(), |
| 2087 " ; literal\n"); |
| 2010 } | 2088 } |
| 2011 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2089 intptr_t value = reinterpret_cast<intptr_t>(literal); |
| 2012 AddObjectTaggedValue(value); | 2090 AddObjectTaggedValue(value); |
| 2013 return; | 2091 return; |
| 2014 } | 2092 } |
| 2015 | 2093 |
| 2016 case Translation::DUPLICATED_OBJECT: { | 2094 case Translation::DUPLICATED_OBJECT: { |
| 2017 int object_index = iterator->Next(); | 2095 int object_index = iterator->Next(); |
| 2018 if (trace_) { | 2096 if (trace_scope_ != NULL) { |
| 2019 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2097 PrintF(trace_scope_->file(), |
| 2098 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2020 reinterpret_cast<intptr_t>(object_slot), | 2099 reinterpret_cast<intptr_t>(object_slot), |
| 2021 field_index); | 2100 field_index); |
| 2022 isolate_->heap()->arguments_marker()->ShortPrint(); | 2101 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2023 PrintF(" ; duplicate of object #%d\n", object_index); | 2102 PrintF(trace_scope_->file(), |
| 2103 " ; duplicate of object #%d\n", object_index); |
| 2024 } | 2104 } |
| 2025 // Use the materialization marker value as a sentinel and fill in | 2105 // Use the materialization marker value as a sentinel and fill in |
| 2026 // the object after the deoptimized frame is built. | 2106 // the object after the deoptimized frame is built. |
| 2027 intptr_t value = reinterpret_cast<intptr_t>( | 2107 intptr_t value = reinterpret_cast<intptr_t>( |
| 2028 isolate_->heap()->arguments_marker()); | 2108 isolate_->heap()->arguments_marker()); |
| 2029 AddObjectDuplication(0, object_index); | 2109 AddObjectDuplication(0, object_index); |
| 2030 AddObjectTaggedValue(value); | 2110 AddObjectTaggedValue(value); |
| 2031 return; | 2111 return; |
| 2032 } | 2112 } |
| 2033 | 2113 |
| 2034 case Translation::ARGUMENTS_OBJECT: | 2114 case Translation::ARGUMENTS_OBJECT: |
| 2035 case Translation::CAPTURED_OBJECT: { | 2115 case Translation::CAPTURED_OBJECT: { |
| 2036 int length = iterator->Next(); | 2116 int length = iterator->Next(); |
| 2037 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; | 2117 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2038 if (trace_) { | 2118 if (trace_scope_ != NULL) { |
| 2039 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", | 2119 PrintF(trace_scope_->file(), |
| 2120 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 2040 reinterpret_cast<intptr_t>(object_slot), | 2121 reinterpret_cast<intptr_t>(object_slot), |
| 2041 field_index); | 2122 field_index); |
| 2042 isolate_->heap()->arguments_marker()->ShortPrint(); | 2123 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2043 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); | 2124 PrintF(trace_scope_->file(), |
| 2125 " ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2044 } | 2126 } |
| 2045 // Use the materialization marker value as a sentinel and fill in | 2127 // Use the materialization marker value as a sentinel and fill in |
| 2046 // the object after the deoptimized frame is built. | 2128 // the object after the deoptimized frame is built. |
| 2047 intptr_t value = reinterpret_cast<intptr_t>( | 2129 intptr_t value = reinterpret_cast<intptr_t>( |
| 2048 isolate_->heap()->arguments_marker()); | 2130 isolate_->heap()->arguments_marker()); |
| 2049 AddObjectStart(0, length, is_args); | 2131 AddObjectStart(0, length, is_args); |
| 2050 AddObjectTaggedValue(value); | 2132 AddObjectTaggedValue(value); |
| 2051 // We save the object values on the side and materialize the actual | 2133 // We save the object values on the side and materialize the actual |
| 2052 // object after the deoptimized frame is built. | 2134 // object after the deoptimized frame is built. |
| 2053 int object_index = deferred_objects_.length() - 1; | 2135 int object_index = deferred_objects_.length() - 1; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2079 case Translation::CONSTRUCT_STUB_FRAME: | 2161 case Translation::CONSTRUCT_STUB_FRAME: |
| 2080 case Translation::GETTER_STUB_FRAME: | 2162 case Translation::GETTER_STUB_FRAME: |
| 2081 case Translation::SETTER_STUB_FRAME: | 2163 case Translation::SETTER_STUB_FRAME: |
| 2082 case Translation::COMPILED_STUB_FRAME: | 2164 case Translation::COMPILED_STUB_FRAME: |
| 2083 UNREACHABLE(); | 2165 UNREACHABLE(); |
| 2084 return; | 2166 return; |
| 2085 | 2167 |
| 2086 case Translation::REGISTER: { | 2168 case Translation::REGISTER: { |
| 2087 int input_reg = iterator->Next(); | 2169 int input_reg = iterator->Next(); |
| 2088 intptr_t input_value = input_->GetRegister(input_reg); | 2170 intptr_t input_value = input_->GetRegister(input_reg); |
| 2089 if (trace_) { | 2171 if (trace_scope_ != NULL) { |
| 2090 PrintF( | 2172 PrintF( |
| 2173 trace_scope_->file(), |
| 2091 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 2174 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
| 2092 output_[frame_index]->GetTop() + output_offset, | 2175 output_[frame_index]->GetTop() + output_offset, |
| 2093 output_offset, | 2176 output_offset, |
| 2094 input_value, | 2177 input_value, |
| 2095 converter.NameOfCPURegister(input_reg)); | 2178 converter.NameOfCPURegister(input_reg)); |
| 2096 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2179 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2097 PrintF("\n"); | 2180 trace_scope_->file()); |
| 2181 PrintF(trace_scope_->file(), "\n"); |
| 2098 } | 2182 } |
| 2099 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 2183 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
| 2100 return; | 2184 return; |
| 2101 } | 2185 } |
| 2102 | 2186 |
| 2103 case Translation::INT32_REGISTER: { | 2187 case Translation::INT32_REGISTER: { |
| 2104 int input_reg = iterator->Next(); | 2188 int input_reg = iterator->Next(); |
| 2105 intptr_t value = input_->GetRegister(input_reg); | 2189 intptr_t value = input_->GetRegister(input_reg); |
| 2106 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2190 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
| 2107 Smi::IsValid(value); | 2191 Smi::IsValid(value); |
| 2108 if (trace_) { | 2192 if (trace_scope_ != NULL) { |
| 2109 PrintF( | 2193 PrintF( |
| 2194 trace_scope_->file(), |
| 2110 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", | 2195 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", |
| 2111 output_[frame_index]->GetTop() + output_offset, | 2196 output_[frame_index]->GetTop() + output_offset, |
| 2112 output_offset, | 2197 output_offset, |
| 2113 value, | 2198 value, |
| 2114 converter.NameOfCPURegister(input_reg), | 2199 converter.NameOfCPURegister(input_reg), |
| 2115 TraceValueType(is_smi, is_native)); | 2200 TraceValueType(is_smi, is_native)); |
| 2116 } | 2201 } |
| 2117 if (is_smi) { | 2202 if (is_smi) { |
| 2118 intptr_t tagged_value = | 2203 intptr_t tagged_value = |
| 2119 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2204 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2120 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2205 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2121 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | 2206 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { |
| 2122 output_[frame_index]->SetFrameSlot(output_offset, value); | 2207 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2123 } else { | 2208 } else { |
| 2124 // We save the untagged value on the side and store a GC-safe | 2209 // We save the untagged value on the side and store a GC-safe |
| 2125 // temporary placeholder in the frame. | 2210 // temporary placeholder in the frame. |
| 2126 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 2211 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
| 2127 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2212 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2128 static_cast<double>(static_cast<int32_t>(value))); | 2213 static_cast<double>(static_cast<int32_t>(value))); |
| 2129 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2214 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2130 } | 2215 } |
| 2131 return; | 2216 return; |
| 2132 } | 2217 } |
| 2133 | 2218 |
| 2134 case Translation::UINT32_REGISTER: { | 2219 case Translation::UINT32_REGISTER: { |
| 2135 int input_reg = iterator->Next(); | 2220 int input_reg = iterator->Next(); |
| 2136 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 2221 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); |
| 2137 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2222 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
| 2138 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2223 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 2139 if (trace_) { | 2224 if (trace_scope_ != NULL) { |
| 2140 PrintF( | 2225 PrintF( |
| 2226 trace_scope_->file(), |
| 2141 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR | 2227 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR |
| 2142 " ; uint %s (%s)\n", | 2228 " ; uint %s (%s)\n", |
| 2143 output_[frame_index]->GetTop() + output_offset, | 2229 output_[frame_index]->GetTop() + output_offset, |
| 2144 output_offset, | 2230 output_offset, |
| 2145 value, | 2231 value, |
| 2146 converter.NameOfCPURegister(input_reg), | 2232 converter.NameOfCPURegister(input_reg), |
| 2147 TraceValueType(is_smi, is_native)); | 2233 TraceValueType(is_smi, is_native)); |
| 2148 } | 2234 } |
| 2149 if (is_smi) { | 2235 if (is_smi) { |
| 2150 intptr_t tagged_value = | 2236 intptr_t tagged_value = |
| 2151 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2237 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2152 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2238 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2153 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | 2239 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { |
| 2154 output_[frame_index]->SetFrameSlot(output_offset, value); | 2240 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2155 } else { | 2241 } else { |
| 2156 // We save the untagged value on the side and store a GC-safe | 2242 // We save the untagged value on the side and store a GC-safe |
| 2157 // temporary placeholder in the frame. | 2243 // temporary placeholder in the frame. |
| 2158 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 2244 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
| 2159 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2245 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2160 static_cast<double>(static_cast<uint32_t>(value))); | 2246 static_cast<double>(static_cast<uint32_t>(value))); |
| 2161 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2247 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2162 } | 2248 } |
| 2163 return; | 2249 return; |
| 2164 } | 2250 } |
| 2165 | 2251 |
| 2166 case Translation::DOUBLE_REGISTER: { | 2252 case Translation::DOUBLE_REGISTER: { |
| 2167 int input_reg = iterator->Next(); | 2253 int input_reg = iterator->Next(); |
| 2168 double value = input_->GetDoubleRegister(input_reg); | 2254 double value = input_->GetDoubleRegister(input_reg); |
| 2169 if (trace_) { | 2255 if (trace_scope_ != NULL) { |
| 2170 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", | 2256 PrintF(trace_scope_->file(), |
| 2257 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", |
| 2171 output_[frame_index]->GetTop() + output_offset, | 2258 output_[frame_index]->GetTop() + output_offset, |
| 2172 output_offset, | 2259 output_offset, |
| 2173 value, | 2260 value, |
| 2174 DoubleRegister::AllocationIndexToString(input_reg)); | 2261 DoubleRegister::AllocationIndexToString(input_reg)); |
| 2175 } | 2262 } |
| 2176 // We save the untagged value on the side and store a GC-safe | 2263 // We save the untagged value on the side and store a GC-safe |
| 2177 // temporary placeholder in the frame. | 2264 // temporary placeholder in the frame. |
| 2178 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 2265 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
| 2179 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2266 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2180 return; | 2267 return; |
| 2181 } | 2268 } |
| 2182 | 2269 |
| 2183 case Translation::STACK_SLOT: { | 2270 case Translation::STACK_SLOT: { |
| 2184 int input_slot_index = iterator->Next(); | 2271 int input_slot_index = iterator->Next(); |
| 2185 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2272 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2186 intptr_t input_value = input_->GetFrameSlot(input_offset); | 2273 intptr_t input_value = input_->GetFrameSlot(input_offset); |
| 2187 if (trace_) { | 2274 if (trace_scope_ != NULL) { |
| 2188 PrintF(" 0x%08" V8PRIxPTR ": ", | 2275 PrintF(trace_scope_->file(), |
| 2276 " 0x%08" V8PRIxPTR ": ", |
| 2189 output_[frame_index]->GetTop() + output_offset); | 2277 output_[frame_index]->GetTop() + output_offset); |
| 2190 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", | 2278 PrintF(trace_scope_->file(), |
| 2279 "[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", |
| 2191 output_offset, | 2280 output_offset, |
| 2192 input_value, | 2281 input_value, |
| 2193 input_offset); | 2282 input_offset); |
| 2194 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 2283 reinterpret_cast<Object*>(input_value)->ShortPrint( |
| 2195 PrintF("\n"); | 2284 trace_scope_->file()); |
| 2285 PrintF(trace_scope_->file(), "\n"); |
| 2196 } | 2286 } |
| 2197 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 2287 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
| 2198 return; | 2288 return; |
| 2199 } | 2289 } |
| 2200 | 2290 |
| 2201 case Translation::INT32_STACK_SLOT: { | 2291 case Translation::INT32_STACK_SLOT: { |
| 2202 int input_slot_index = iterator->Next(); | 2292 int input_slot_index = iterator->Next(); |
| 2203 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2293 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2204 intptr_t value = input_->GetFrameSlot(input_offset); | 2294 intptr_t value = input_->GetFrameSlot(input_offset); |
| 2205 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2295 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
| 2206 Smi::IsValid(value); | 2296 Smi::IsValid(value); |
| 2207 if (trace_) { | 2297 if (trace_scope_ != NULL) { |
| 2208 PrintF(" 0x%08" V8PRIxPTR ": ", | 2298 PrintF(trace_scope_->file(), |
| 2299 " 0x%08" V8PRIxPTR ": ", |
| 2209 output_[frame_index]->GetTop() + output_offset); | 2300 output_[frame_index]->GetTop() + output_offset); |
| 2210 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", | 2301 PrintF(trace_scope_->file(), |
| 2302 "[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", |
| 2211 output_offset, | 2303 output_offset, |
| 2212 value, | 2304 value, |
| 2213 input_offset, | 2305 input_offset, |
| 2214 TraceValueType(is_smi, is_native)); | 2306 TraceValueType(is_smi, is_native)); |
| 2215 } | 2307 } |
| 2216 if (is_smi) { | 2308 if (is_smi) { |
| 2217 intptr_t tagged_value = | 2309 intptr_t tagged_value = |
| 2218 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2310 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2219 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2311 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2220 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | 2312 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { |
| 2221 output_[frame_index]->SetFrameSlot(output_offset, value); | 2313 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2222 } else { | 2314 } else { |
| 2223 // We save the untagged value on the side and store a GC-safe | 2315 // We save the untagged value on the side and store a GC-safe |
| 2224 // temporary placeholder in the frame. | 2316 // temporary placeholder in the frame. |
| 2225 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 2317 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
| 2226 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2318 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2227 static_cast<double>(static_cast<int32_t>(value))); | 2319 static_cast<double>(static_cast<int32_t>(value))); |
| 2228 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2320 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2229 } | 2321 } |
| 2230 return; | 2322 return; |
| 2231 } | 2323 } |
| 2232 | 2324 |
| 2233 case Translation::UINT32_STACK_SLOT: { | 2325 case Translation::UINT32_STACK_SLOT: { |
| 2234 int input_slot_index = iterator->Next(); | 2326 int input_slot_index = iterator->Next(); |
| 2235 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2327 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2236 uintptr_t value = | 2328 uintptr_t value = |
| 2237 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 2329 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
| 2238 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && | 2330 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
| 2239 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 2331 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
| 2240 if (trace_) { | 2332 if (trace_scope_ != NULL) { |
| 2241 PrintF(" 0x%08" V8PRIxPTR ": ", | 2333 PrintF(trace_scope_->file(), |
| 2334 " 0x%08" V8PRIxPTR ": ", |
| 2242 output_[frame_index]->GetTop() + output_offset); | 2335 output_[frame_index]->GetTop() + output_offset); |
| 2243 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", | 2336 PrintF(trace_scope_->file(), |
| 2337 "[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", |
| 2244 output_offset, | 2338 output_offset, |
| 2245 value, | 2339 value, |
| 2246 input_offset, | 2340 input_offset, |
| 2247 TraceValueType(is_smi, is_native)); | 2341 TraceValueType(is_smi, is_native)); |
| 2248 } | 2342 } |
| 2249 if (is_smi) { | 2343 if (is_smi) { |
| 2250 intptr_t tagged_value = | 2344 intptr_t tagged_value = |
| 2251 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 2345 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
| 2252 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 2346 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
| 2253 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { | 2347 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { |
| 2254 output_[frame_index]->SetFrameSlot(output_offset, value); | 2348 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2255 } else { | 2349 } else { |
| 2256 // We save the untagged value on the side and store a GC-safe | 2350 // We save the untagged value on the side and store a GC-safe |
| 2257 // temporary placeholder in the frame. | 2351 // temporary placeholder in the frame. |
| 2258 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); | 2352 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); |
| 2259 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 2353 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
| 2260 static_cast<double>(static_cast<uint32_t>(value))); | 2354 static_cast<double>(static_cast<uint32_t>(value))); |
| 2261 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2355 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2262 } | 2356 } |
| 2263 return; | 2357 return; |
| 2264 } | 2358 } |
| 2265 | 2359 |
| 2266 case Translation::DOUBLE_STACK_SLOT: { | 2360 case Translation::DOUBLE_STACK_SLOT: { |
| 2267 int input_slot_index = iterator->Next(); | 2361 int input_slot_index = iterator->Next(); |
| 2268 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); | 2362 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
| 2269 double value = input_->GetDoubleFrameSlot(input_offset); | 2363 double value = input_->GetDoubleFrameSlot(input_offset); |
| 2270 if (trace_) { | 2364 if (trace_scope_ != NULL) { |
| 2271 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", | 2365 PrintF(trace_scope_->file(), |
| 2366 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", |
| 2272 output_[frame_index]->GetTop() + output_offset, | 2367 output_[frame_index]->GetTop() + output_offset, |
| 2273 output_offset, | 2368 output_offset, |
| 2274 value, | 2369 value, |
| 2275 input_offset); | 2370 input_offset); |
| 2276 } | 2371 } |
| 2277 // We save the untagged value on the side and store a GC-safe | 2372 // We save the untagged value on the side and store a GC-safe |
| 2278 // temporary placeholder in the frame. | 2373 // temporary placeholder in the frame. |
| 2279 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 2374 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
| 2280 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 2375 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
| 2281 return; | 2376 return; |
| 2282 } | 2377 } |
| 2283 | 2378 |
| 2284 case Translation::LITERAL: { | 2379 case Translation::LITERAL: { |
| 2285 Object* literal = ComputeLiteral(iterator->Next()); | 2380 Object* literal = ComputeLiteral(iterator->Next()); |
| 2286 if (trace_) { | 2381 if (trace_scope_ != NULL) { |
| 2287 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2382 PrintF(trace_scope_->file(), |
| 2383 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2288 output_[frame_index]->GetTop() + output_offset, | 2384 output_[frame_index]->GetTop() + output_offset, |
| 2289 output_offset); | 2385 output_offset); |
| 2290 literal->ShortPrint(); | 2386 literal->ShortPrint(trace_scope_->file()); |
| 2291 PrintF(" ; literal\n"); | 2387 PrintF(trace_scope_->file(), " ; literal\n"); |
| 2292 } | 2388 } |
| 2293 intptr_t value = reinterpret_cast<intptr_t>(literal); | 2389 intptr_t value = reinterpret_cast<intptr_t>(literal); |
| 2294 output_[frame_index]->SetFrameSlot(output_offset, value); | 2390 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2295 return; | 2391 return; |
| 2296 } | 2392 } |
| 2297 | 2393 |
| 2298 case Translation::DUPLICATED_OBJECT: { | 2394 case Translation::DUPLICATED_OBJECT: { |
| 2299 int object_index = iterator->Next(); | 2395 int object_index = iterator->Next(); |
| 2300 if (trace_) { | 2396 if (trace_scope_ != NULL) { |
| 2301 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2397 PrintF(trace_scope_->file(), |
| 2398 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2302 output_[frame_index]->GetTop() + output_offset, | 2399 output_[frame_index]->GetTop() + output_offset, |
| 2303 output_offset); | 2400 output_offset); |
| 2304 isolate_->heap()->arguments_marker()->ShortPrint(); | 2401 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2305 PrintF(" ; duplicate of object #%d\n", object_index); | 2402 PrintF(trace_scope_->file(), |
| 2403 " ; duplicate of object #%d\n", object_index); |
| 2306 } | 2404 } |
| 2307 // Use the materialization marker value as a sentinel and fill in | 2405 // Use the materialization marker value as a sentinel and fill in |
| 2308 // the object after the deoptimized frame is built. | 2406 // the object after the deoptimized frame is built. |
| 2309 intptr_t value = reinterpret_cast<intptr_t>( | 2407 intptr_t value = reinterpret_cast<intptr_t>( |
| 2310 isolate_->heap()->arguments_marker()); | 2408 isolate_->heap()->arguments_marker()); |
| 2311 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, | 2409 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, |
| 2312 object_index); | 2410 object_index); |
| 2313 output_[frame_index]->SetFrameSlot(output_offset, value); | 2411 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2314 return; | 2412 return; |
| 2315 } | 2413 } |
| 2316 | 2414 |
| 2317 case Translation::ARGUMENTS_OBJECT: | 2415 case Translation::ARGUMENTS_OBJECT: |
| 2318 case Translation::CAPTURED_OBJECT: { | 2416 case Translation::CAPTURED_OBJECT: { |
| 2319 int length = iterator->Next(); | 2417 int length = iterator->Next(); |
| 2320 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; | 2418 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; |
| 2321 if (trace_) { | 2419 if (trace_scope_ != NULL) { |
| 2322 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 2420 PrintF(trace_scope_->file(), |
| 2421 " 0x%08" V8PRIxPTR ": [top + %d] <- ", |
| 2323 output_[frame_index]->GetTop() + output_offset, | 2422 output_[frame_index]->GetTop() + output_offset, |
| 2324 output_offset); | 2423 output_offset); |
| 2325 isolate_->heap()->arguments_marker()->ShortPrint(); | 2424 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file()); |
| 2326 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); | 2425 PrintF(trace_scope_->file(), |
| 2426 " ; object (length = %d, is_args = %d)\n", length, is_args); |
| 2327 } | 2427 } |
| 2328 // Use the materialization marker value as a sentinel and fill in | 2428 // Use the materialization marker value as a sentinel and fill in |
| 2329 // the object after the deoptimized frame is built. | 2429 // the object after the deoptimized frame is built. |
| 2330 intptr_t value = reinterpret_cast<intptr_t>( | 2430 intptr_t value = reinterpret_cast<intptr_t>( |
| 2331 isolate_->heap()->arguments_marker()); | 2431 isolate_->heap()->arguments_marker()); |
| 2332 AddObjectStart(output_[frame_index]->GetTop() + output_offset, | 2432 AddObjectStart(output_[frame_index]->GetTop() + output_offset, |
| 2333 length, is_args); | 2433 length, is_args); |
| 2334 output_[frame_index]->SetFrameSlot(output_offset, value); | 2434 output_[frame_index]->SetFrameSlot(output_offset, value); |
| 2335 // We save the object values on the side and materialize the actual | 2435 // We save the object values on the side and materialize the actual |
| 2336 // object after the deoptimized frame is built. | 2436 // object after the deoptimized frame is built. |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2945 | 3045 |
| 2946 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3046 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 2947 v->VisitPointer(BitCast<Object**>(&function_)); | 3047 v->VisitPointer(BitCast<Object**>(&function_)); |
| 2948 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3048 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 2949 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3049 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 2950 } | 3050 } |
| 2951 | 3051 |
| 2952 #endif // ENABLE_DEBUGGER_SUPPORT | 3052 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2953 | 3053 |
| 2954 } } // namespace v8::internal | 3054 } } // namespace v8::internal |
| OLD | NEW |