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 |