Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: src/deoptimizer.cc

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/deoptimizer.h ('k') | src/disassembler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
1416 // The output frame must have room for all pushed register parameters 1456 // The output frame must have room for all pushed register parameters
1417 // and the standard stack frame slots. Include space for an argument 1457 // and the standard stack frame slots. Include space for an argument
1418 // object to the callee and optionally the space to pass the argument 1458 // object to the callee and optionally the space to pass the argument
1419 // object to the stub failure handler. 1459 // object to the stub failure handler.
1420 ASSERT(descriptor->register_param_count_ >= 0); 1460 ASSERT(descriptor->register_param_count_ >= 0);
1421 int height_in_bytes = kPointerSize * descriptor->register_param_count_ + 1461 int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
1422 sizeof(Arguments) + kPointerSize; 1462 sizeof(Arguments) + kPointerSize;
1423 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; 1463 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
1424 int input_frame_size = input_->GetFrameSize(); 1464 int input_frame_size = input_->GetFrameSize();
1425 int output_frame_size = height_in_bytes + fixed_frame_size; 1465 int output_frame_size = height_in_bytes + fixed_frame_size;
1426 if (trace_) { 1466 if (trace_scope_ != NULL) {
1427 PrintF(" translating %s => StubFailureTrampolineStub, height=%d\n", 1467 PrintF(trace_scope_->file(),
1468 " translating %s => StubFailureTrampolineStub, height=%d\n",
1428 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), 1469 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false),
1429 height_in_bytes); 1470 height_in_bytes);
1430 } 1471 }
1431 1472
1432 // The stub failure trampoline is a single frame. 1473 // The stub failure trampoline is a single frame.
1433 FrameDescription* output_frame = 1474 FrameDescription* output_frame =
1434 new(output_frame_size) FrameDescription(output_frame_size, NULL); 1475 new(output_frame_size) FrameDescription(output_frame_size, NULL);
1435 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); 1476 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1436 ASSERT(frame_index == 0); 1477 ASSERT(frame_index == 0);
1437 output_[frame_index] = output_frame; 1478 output_[frame_index] = output_frame;
1438 1479
1439 // The top address for the output frame can be computed from the input 1480 // The top address for the output frame can be computed from the input
1440 // frame pointer and the output frame's height. Subtract space for the 1481 // frame pointer and the output frame's height. Subtract space for the
1441 // context and function slots. 1482 // context and function slots.
1442 Register fp_reg = StubFailureTrampolineFrame::fp_register(); 1483 Register fp_reg = StubFailureTrampolineFrame::fp_register();
1443 intptr_t top_address = input_->GetRegister(fp_reg.code()) - 1484 intptr_t top_address = input_->GetRegister(fp_reg.code()) -
1444 (2 * kPointerSize) - height_in_bytes; 1485 (2 * kPointerSize) - height_in_bytes;
1445 output_frame->SetTop(top_address); 1486 output_frame->SetTop(top_address);
1446 1487
1447 // Read caller's PC (JSFunction continuation) from the input frame. 1488 // Read caller's PC (JSFunction continuation) from the input frame.
1448 unsigned input_frame_offset = input_frame_size - kPCOnStackSize; 1489 unsigned input_frame_offset = input_frame_size - kPCOnStackSize;
1449 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; 1490 unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
1450 intptr_t value = input_->GetFrameSlot(input_frame_offset); 1491 intptr_t value = input_->GetFrameSlot(input_frame_offset);
1451 output_frame->SetCallerPc(output_frame_offset, value); 1492 output_frame->SetCallerPc(output_frame_offset, value);
1452 if (trace_) { 1493 if (trace_scope_ != NULL) {
1453 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1494 PrintF(trace_scope_->file(),
1495 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1454 V8PRIxPTR " ; caller's pc\n", 1496 V8PRIxPTR " ; caller's pc\n",
1455 top_address + output_frame_offset, output_frame_offset, value); 1497 top_address + output_frame_offset, output_frame_offset, value);
1456 } 1498 }
1457 1499
1458 // Read caller's FP from the input frame, and set this frame's FP. 1500 // Read caller's FP from the input frame, and set this frame's FP.
1459 input_frame_offset -= kFPOnStackSize; 1501 input_frame_offset -= kFPOnStackSize;
1460 value = input_->GetFrameSlot(input_frame_offset); 1502 value = input_->GetFrameSlot(input_frame_offset);
1461 output_frame_offset -= kFPOnStackSize; 1503 output_frame_offset -= kFPOnStackSize;
1462 output_frame->SetCallerFp(output_frame_offset, value); 1504 output_frame->SetCallerFp(output_frame_offset, value);
1463 intptr_t frame_ptr = input_->GetRegister(fp_reg.code()); 1505 intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
1464 output_frame->SetRegister(fp_reg.code(), frame_ptr); 1506 output_frame->SetRegister(fp_reg.code(), frame_ptr);
1465 output_frame->SetFp(frame_ptr); 1507 output_frame->SetFp(frame_ptr);
1466 if (trace_) { 1508 if (trace_scope_ != NULL) {
1467 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1509 PrintF(trace_scope_->file(),
1510 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1468 V8PRIxPTR " ; caller's fp\n", 1511 V8PRIxPTR " ; caller's fp\n",
1469 top_address + output_frame_offset, output_frame_offset, value); 1512 top_address + output_frame_offset, output_frame_offset, value);
1470 } 1513 }
1471 1514
1472 // The context can be gotten from the input frame. 1515 // The context can be gotten from the input frame.
1473 Register context_reg = StubFailureTrampolineFrame::context_register(); 1516 Register context_reg = StubFailureTrampolineFrame::context_register();
1474 input_frame_offset -= kPointerSize; 1517 input_frame_offset -= kPointerSize;
1475 value = input_->GetFrameSlot(input_frame_offset); 1518 value = input_->GetFrameSlot(input_frame_offset);
1476 output_frame->SetRegister(context_reg.code(), value); 1519 output_frame->SetRegister(context_reg.code(), value);
1477 output_frame_offset -= kPointerSize; 1520 output_frame_offset -= kPointerSize;
1478 output_frame->SetFrameSlot(output_frame_offset, value); 1521 output_frame->SetFrameSlot(output_frame_offset, value);
1479 if (trace_) { 1522 if (trace_scope_ != NULL) {
1480 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1523 PrintF(trace_scope_->file(),
1524 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1481 V8PRIxPTR " ; context\n", 1525 V8PRIxPTR " ; context\n",
1482 top_address + output_frame_offset, output_frame_offset, value); 1526 top_address + output_frame_offset, output_frame_offset, value);
1483 } 1527 }
1484 1528
1485 // A marker value is used in place of the function. 1529 // A marker value is used in place of the function.
1486 output_frame_offset -= kPointerSize; 1530 output_frame_offset -= kPointerSize;
1487 value = reinterpret_cast<intptr_t>( 1531 value = reinterpret_cast<intptr_t>(
1488 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); 1532 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
1489 output_frame->SetFrameSlot(output_frame_offset, value); 1533 output_frame->SetFrameSlot(output_frame_offset, value);
1490 if (trace_) { 1534 if (trace_scope_ != NULL) {
1491 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1535 PrintF(trace_scope_->file(),
1536 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1492 V8PRIxPTR " ; function (stub failure sentinel)\n", 1537 V8PRIxPTR " ; function (stub failure sentinel)\n",
1493 top_address + output_frame_offset, output_frame_offset, value); 1538 top_address + output_frame_offset, output_frame_offset, value);
1494 } 1539 }
1495 1540
1496 intptr_t caller_arg_count = 0; 1541 intptr_t caller_arg_count = 0;
1497 bool arg_count_known = !descriptor->stack_parameter_count_.is_valid(); 1542 bool arg_count_known = !descriptor->stack_parameter_count_.is_valid();
1498 1543
1499 // Build the Arguments object for the caller's parameters and a pointer to it. 1544 // Build the Arguments object for the caller's parameters and a pointer to it.
1500 output_frame_offset -= kPointerSize; 1545 output_frame_offset -= kPointerSize;
1501 int args_arguments_offset = output_frame_offset; 1546 int args_arguments_offset = output_frame_offset;
1502 intptr_t the_hole = reinterpret_cast<intptr_t>( 1547 intptr_t the_hole = reinterpret_cast<intptr_t>(
1503 isolate_->heap()->the_hole_value()); 1548 isolate_->heap()->the_hole_value());
1504 if (arg_count_known) { 1549 if (arg_count_known) {
1505 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + 1550 value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1506 (caller_arg_count - 1) * kPointerSize; 1551 (caller_arg_count - 1) * kPointerSize;
1507 } else { 1552 } else {
1508 value = the_hole; 1553 value = the_hole;
1509 } 1554 }
1510 1555
1511 output_frame->SetFrameSlot(args_arguments_offset, value); 1556 output_frame->SetFrameSlot(args_arguments_offset, value);
1512 if (trace_) { 1557 if (trace_scope_ != NULL) {
1513 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1558 PrintF(trace_scope_->file(),
1559 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1514 V8PRIxPTR " ; args.arguments %s\n", 1560 V8PRIxPTR " ; args.arguments %s\n",
1515 top_address + args_arguments_offset, args_arguments_offset, value, 1561 top_address + args_arguments_offset, args_arguments_offset, value,
1516 arg_count_known ? "" : "(the hole)"); 1562 arg_count_known ? "" : "(the hole)");
1517 } 1563 }
1518 1564
1519 output_frame_offset -= kPointerSize; 1565 output_frame_offset -= kPointerSize;
1520 int length_frame_offset = output_frame_offset; 1566 int length_frame_offset = output_frame_offset;
1521 value = arg_count_known ? caller_arg_count : the_hole; 1567 value = arg_count_known ? caller_arg_count : the_hole;
1522 output_frame->SetFrameSlot(length_frame_offset, value); 1568 output_frame->SetFrameSlot(length_frame_offset, value);
1523 if (trace_) { 1569 if (trace_scope_ != NULL) {
1524 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1570 PrintF(trace_scope_->file(),
1571 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1525 V8PRIxPTR " ; args.length %s\n", 1572 V8PRIxPTR " ; args.length %s\n",
1526 top_address + length_frame_offset, length_frame_offset, value, 1573 top_address + length_frame_offset, length_frame_offset, value,
1527 arg_count_known ? "" : "(the hole)"); 1574 arg_count_known ? "" : "(the hole)");
1528 } 1575 }
1529 1576
1530 output_frame_offset -= kPointerSize; 1577 output_frame_offset -= kPointerSize;
1531 value = frame_ptr + StandardFrameConstants::kCallerSPOffset - 1578 value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
1532 (output_frame_size - output_frame_offset) + kPointerSize; 1579 (output_frame_size - output_frame_offset) + kPointerSize;
1533 output_frame->SetFrameSlot(output_frame_offset, value); 1580 output_frame->SetFrameSlot(output_frame_offset, value);
1534 if (trace_) { 1581 if (trace_scope_ != NULL) {
1535 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1582 PrintF(trace_scope_->file(),
1583 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1536 V8PRIxPTR " ; args*\n", 1584 V8PRIxPTR " ; args*\n",
1537 top_address + output_frame_offset, output_frame_offset, value); 1585 top_address + output_frame_offset, output_frame_offset, value);
1538 } 1586 }
1539 1587
1540 // Copy the register parameters to the failure frame. 1588 // Copy the register parameters to the failure frame.
1589 int arguments_length_offset = -1;
1541 for (int i = 0; i < descriptor->register_param_count_; ++i) { 1590 for (int i = 0; i < descriptor->register_param_count_; ++i) {
1542 output_frame_offset -= kPointerSize; 1591 output_frame_offset -= kPointerSize;
1543 DoTranslateCommand(iterator, 0, output_frame_offset); 1592 DoTranslateCommand(iterator, 0, output_frame_offset);
1544 }
1545 1593
1546 if (!arg_count_known) { 1594 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) {
1547 DoTranslateCommand(iterator, 0, length_frame_offset, 1595 arguments_length_offset = output_frame_offset;
1548 TRANSLATED_VALUE_IS_NATIVE);
1549 caller_arg_count = output_frame->GetFrameSlot(length_frame_offset);
1550 value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1551 (caller_arg_count - 1) * kPointerSize;
1552 output_frame->SetFrameSlot(args_arguments_offset, value);
1553 if (trace_) {
1554 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1555 V8PRIxPTR " ; args.arguments\n",
1556 top_address + args_arguments_offset, args_arguments_offset, value);
1557 } 1596 }
1558 } 1597 }
1559 1598
1560 ASSERT(0 == output_frame_offset); 1599 ASSERT(0 == output_frame_offset);
1561 1600
1601 if (!arg_count_known) {
1602 ASSERT(arguments_length_offset >= 0);
1603 // We know it's a smi because 1) the code stub guarantees the stack
1604 // parameter count is in smi range, and 2) the DoTranslateCommand in the
1605 // parameter loop above translated that to a tagged value.
1606 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
1607 output_frame->GetFrameSlot(arguments_length_offset));
1608 caller_arg_count = smi_caller_arg_count->value();
1609 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1610 if (trace_scope_ != NULL) {
1611 PrintF(trace_scope_->file(),
1612 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1613 V8PRIxPTR " ; args.length\n",
1614 top_address + length_frame_offset, length_frame_offset,
1615 caller_arg_count);
1616 }
1617 value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
1618 (caller_arg_count - 1) * kPointerSize;
1619 output_frame->SetFrameSlot(args_arguments_offset, value);
1620 if (trace_scope_ != NULL) {
1621 PrintF(trace_scope_->file(),
1622 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1623 V8PRIxPTR " ; args.arguments\n",
1624 top_address + args_arguments_offset, args_arguments_offset,
1625 value);
1626 }
1627 }
1628
1562 // Copy the double registers from the input into the output frame. 1629 // Copy the double registers from the input into the output frame.
1563 CopyDoubleRegisters(output_frame); 1630 CopyDoubleRegisters(output_frame);
1564 1631
1565 // Fill registers containing handler and number of parameters. 1632 // Fill registers containing handler and number of parameters.
1566 SetPlatformCompiledStubRegisters(output_frame, descriptor); 1633 SetPlatformCompiledStubRegisters(output_frame, descriptor);
1567 1634
1568 // Compute this frame's PC, state, and continuation. 1635 // Compute this frame's PC, state, and continuation.
1569 Code* trampoline = NULL; 1636 Code* trampoline = NULL;
1570 StubFunctionMode function_mode = descriptor->function_mode_; 1637 StubFunctionMode function_mode = descriptor->function_mode_;
1571 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, 1638 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 array->set(i, *value); 1680 array->set(i, *value);
1614 } 1681 }
1615 } else { 1682 } else {
1616 // Dispatch on the instance type of the object to be materialized. 1683 // Dispatch on the instance type of the object to be materialized.
1617 // We also need to make sure that the representation of all fields 1684 // We also need to make sure that the representation of all fields
1618 // in the given object are general enough to hold a tagged value. 1685 // in the given object are general enough to hold a tagged value.
1619 Handle<Map> map = Map::GeneralizeAllFieldRepresentations( 1686 Handle<Map> map = Map::GeneralizeAllFieldRepresentations(
1620 Handle<Map>::cast(MaterializeNextValue()), Representation::Tagged()); 1687 Handle<Map>::cast(MaterializeNextValue()), Representation::Tagged());
1621 switch (map->instance_type()) { 1688 switch (map->instance_type()) {
1622 case HEAP_NUMBER_TYPE: { 1689 case HEAP_NUMBER_TYPE: {
1623 Handle<HeapNumber> object = isolate_->factory()->NewHeapNumber(0.0); 1690 // Reuse the HeapNumber value directly as it is already properly
1691 // tagged and skip materializing the HeapNumber explicitly.
1692 Handle<Object> object = MaterializeNextValue();
1624 materialized_objects_->Add(object); 1693 materialized_objects_->Add(object);
1625 Handle<Object> number = MaterializeNextValue();
1626 object->set_value(number->Number());
1627 materialization_value_index_ += kDoubleSize / kPointerSize - 1; 1694 materialization_value_index_ += kDoubleSize / kPointerSize - 1;
1628 break; 1695 break;
1629 } 1696 }
1630 case JS_OBJECT_TYPE: { 1697 case JS_OBJECT_TYPE: {
1631 Handle<JSObject> object = 1698 Handle<JSObject> object =
1632 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); 1699 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED, false);
1633 materialized_objects_->Add(object); 1700 materialized_objects_->Add(object);
1634 Handle<Object> properties = MaterializeNextValue(); 1701 Handle<Object> properties = MaterializeNextValue();
1635 Handle<Object> elements = MaterializeNextValue(); 1702 Handle<Object> elements = MaterializeNextValue();
1636 object->set_properties(FixedArray::cast(*properties)); 1703 object->set_properties(FixedArray::cast(*properties));
(...skipping 10 matching lines...) Expand all
1647 materialized_objects_->Add(object); 1714 materialized_objects_->Add(object);
1648 Handle<Object> properties = MaterializeNextValue(); 1715 Handle<Object> properties = MaterializeNextValue();
1649 Handle<Object> elements = MaterializeNextValue(); 1716 Handle<Object> elements = MaterializeNextValue();
1650 Handle<Object> length = MaterializeNextValue(); 1717 Handle<Object> length = MaterializeNextValue();
1651 object->set_properties(FixedArray::cast(*properties)); 1718 object->set_properties(FixedArray::cast(*properties));
1652 object->set_elements(FixedArrayBase::cast(*elements)); 1719 object->set_elements(FixedArrayBase::cast(*elements));
1653 object->set_length(*length); 1720 object->set_length(*length);
1654 break; 1721 break;
1655 } 1722 }
1656 default: 1723 default:
1657 PrintF("[couldn't handle instance type %d]\n", map->instance_type()); 1724 PrintF(stderr,
1725 "[couldn't handle instance type %d]\n", map->instance_type());
1658 UNREACHABLE(); 1726 UNREACHABLE();
1659 } 1727 }
1660 } 1728 }
1661 1729
1662 return materialized_objects_->at(object_index); 1730 return materialized_objects_->at(object_index);
1663 } 1731 }
1664 1732
1665 1733
1666 Handle<Object> Deoptimizer::MaterializeNextValue() { 1734 Handle<Object> Deoptimizer::MaterializeNextValue() {
1667 int value_index = materialization_value_index_++; 1735 int value_index = materialization_value_index_++;
(...skipping 24 matching lines...) Expand all
1692 1760
1693 // Play it safe and clear all unhandlified values before we continue. 1761 // Play it safe and clear all unhandlified values before we continue.
1694 deferred_objects_tagged_values_.Clear(); 1762 deferred_objects_tagged_values_.Clear();
1695 1763
1696 // Materialize all heap numbers before looking at arguments because when the 1764 // Materialize all heap numbers before looking at arguments because when the
1697 // output frames are used to materialize arguments objects later on they need 1765 // output frames are used to materialize arguments objects later on they need
1698 // to already contain valid heap numbers. 1766 // to already contain valid heap numbers.
1699 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 1767 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
1700 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; 1768 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
1701 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 1769 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1702 if (trace_) { 1770 if (trace_scope_ != NULL) {
1703 PrintF("Materialized a new heap number %p [%e] in slot %p\n", 1771 PrintF(trace_scope_->file(),
1772 "Materialized a new heap number %p [%e] in slot %p\n",
1704 reinterpret_cast<void*>(*num), 1773 reinterpret_cast<void*>(*num),
1705 d.value(), 1774 d.value(),
1706 d.destination()); 1775 d.destination());
1707 } 1776 }
1708 Memory::Object_at(d.destination()) = *num; 1777 Memory::Object_at(d.destination()) = *num;
1709 } 1778 }
1710 1779
1711 // Materialize all heap numbers required for arguments/captured objects. 1780 // Materialize all heap numbers required for arguments/captured objects.
1712 for (int i = 0; i < deferred_objects_double_values_.length(); i++) { 1781 for (int i = 0; i < deferred_objects_double_values_.length(); i++) {
1713 HeapNumberMaterializationDescriptor<int> d = 1782 HeapNumberMaterializationDescriptor<int> d =
1714 deferred_objects_double_values_[i]; 1783 deferred_objects_double_values_[i];
1715 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 1784 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1716 if (trace_) { 1785 if (trace_scope_ != NULL) {
1717 PrintF("Materialized a new heap number %p [%e] for object at %d\n", 1786 PrintF(trace_scope_->file(),
1787 "Materialized a new heap number %p [%e] for object at %d\n",
1718 reinterpret_cast<void*>(*num), 1788 reinterpret_cast<void*>(*num),
1719 d.value(), 1789 d.value(),
1720 d.destination()); 1790 d.destination());
1721 } 1791 }
1722 ASSERT(values.at(d.destination())->IsTheHole()); 1792 ASSERT(values.at(d.destination())->IsTheHole());
1723 values.Set(d.destination(), num); 1793 values.Set(d.destination(), num);
1724 } 1794 }
1725 1795
1726 // Play it safe and clear all object double values before we continue. 1796 // Play it safe and clear all object double values before we continue.
1727 deferred_objects_double_values_.Clear(); 1797 deferred_objects_double_values_.Clear();
1728 1798
1729 // Materialize arguments/captured objects. 1799 // Materialize arguments/captured objects.
1730 if (!deferred_objects_.is_empty()) { 1800 if (!deferred_objects_.is_empty()) {
1731 List<Handle<Object> > materialized_objects(deferred_objects_.length()); 1801 List<Handle<Object> > materialized_objects(deferred_objects_.length());
1732 materialized_objects_ = &materialized_objects; 1802 materialized_objects_ = &materialized_objects;
1733 materialized_values_ = &values; 1803 materialized_values_ = &values;
1734 1804
1735 while (materialization_object_index_ < deferred_objects_.length()) { 1805 while (materialization_object_index_ < deferred_objects_.length()) {
1736 int object_index = materialization_object_index_; 1806 int object_index = materialization_object_index_;
1737 ObjectMaterializationDescriptor descriptor = 1807 ObjectMaterializationDescriptor descriptor =
1738 deferred_objects_.at(object_index); 1808 deferred_objects_.at(object_index);
1739 1809
1740 // Find a previously materialized object by de-duplication or 1810 // Find a previously materialized object by de-duplication or
1741 // materialize a new instance of the object if necessary. Store 1811 // materialize a new instance of the object if necessary. Store
1742 // the materialized object into the frame slot. 1812 // the materialized object into the frame slot.
1743 Handle<Object> object = MaterializeNextHeapObject(); 1813 Handle<Object> object = MaterializeNextHeapObject();
1744 Memory::Object_at(descriptor.slot_address()) = *object; 1814 Memory::Object_at(descriptor.slot_address()) = *object;
1745 if (trace_) { 1815 if (trace_scope_ != NULL) {
1746 if (descriptor.is_arguments()) { 1816 if (descriptor.is_arguments()) {
1747 PrintF("Materialized %sarguments object of length %d for %p: ", 1817 PrintF(trace_scope_->file(),
1818 "Materialized %sarguments object of length %d for %p: ",
1748 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", 1819 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "",
1749 Handle<JSObject>::cast(object)->elements()->length(), 1820 Handle<JSObject>::cast(object)->elements()->length(),
1750 reinterpret_cast<void*>(descriptor.slot_address())); 1821 reinterpret_cast<void*>(descriptor.slot_address()));
1751 } else { 1822 } else {
1752 PrintF("Materialized captured object of size %d for %p: ", 1823 PrintF(trace_scope_->file(),
1824 "Materialized captured object of size %d for %p: ",
1753 Handle<HeapObject>::cast(object)->Size(), 1825 Handle<HeapObject>::cast(object)->Size(),
1754 reinterpret_cast<void*>(descriptor.slot_address())); 1826 reinterpret_cast<void*>(descriptor.slot_address()));
1755 } 1827 }
1756 object->ShortPrint(); 1828 object->ShortPrint(trace_scope_->file());
1757 PrintF("\n"); 1829 PrintF(trace_scope_->file(), "\n");
1758 } 1830 }
1759 } 1831 }
1760 1832
1761 ASSERT(materialization_object_index_ == materialized_objects_->length()); 1833 ASSERT(materialization_object_index_ == materialized_objects_->length());
1762 ASSERT(materialization_value_index_ == materialized_values_->length()); 1834 ASSERT(materialization_value_index_ == materialized_values_->length());
1763 } 1835 }
1764 } 1836 }
1765 1837
1766 1838
1767 #ifdef ENABLE_DEBUGGER_SUPPORT 1839 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 11 matching lines...) Expand all
1779 1851
1780 // Check of the heap number to materialize actually belong to the frame 1852 // Check of the heap number to materialize actually belong to the frame
1781 // being extracted. 1853 // being extracted.
1782 Address slot = d.destination(); 1854 Address slot = d.destination();
1783 if (parameters_top <= slot && slot < parameters_bottom) { 1855 if (parameters_top <= slot && slot < parameters_bottom) {
1784 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 1856 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1785 1857
1786 int index = (info->parameters_count() - 1) - 1858 int index = (info->parameters_count() - 1) -
1787 static_cast<int>(slot - parameters_top) / kPointerSize; 1859 static_cast<int>(slot - parameters_top) / kPointerSize;
1788 1860
1789 if (trace_) { 1861 if (trace_scope_ != NULL) {
1790 PrintF("Materializing a new heap number %p [%e] in slot %p" 1862 PrintF(trace_scope_->file(),
1863 "Materializing a new heap number %p [%e] in slot %p"
1791 "for parameter slot #%d\n", 1864 "for parameter slot #%d\n",
1792 reinterpret_cast<void*>(*num), 1865 reinterpret_cast<void*>(*num),
1793 d.value(), 1866 d.value(),
1794 d.destination(), 1867 d.destination(),
1795 index); 1868 index);
1796 } 1869 }
1797 1870
1798 info->SetParameter(index, *num); 1871 info->SetParameter(index, *num);
1799 } else if (expressions_top <= slot && slot < expressions_bottom) { 1872 } else if (expressions_top <= slot && slot < expressions_bottom) {
1800 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 1873 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
1801 1874
1802 int index = info->expression_count() - 1 - 1875 int index = info->expression_count() - 1 -
1803 static_cast<int>(slot - expressions_top) / kPointerSize; 1876 static_cast<int>(slot - expressions_top) / kPointerSize;
1804 1877
1805 if (trace_) { 1878 if (trace_scope_ != NULL) {
1806 PrintF("Materializing a new heap number %p [%e] in slot %p" 1879 PrintF(trace_scope_->file(),
1880 "Materializing a new heap number %p [%e] in slot %p"
1807 "for expression slot #%d\n", 1881 "for expression slot #%d\n",
1808 reinterpret_cast<void*>(*num), 1882 reinterpret_cast<void*>(*num),
1809 d.value(), 1883 d.value(),
1810 d.destination(), 1884 d.destination(),
1811 index); 1885 index);
1812 } 1886 }
1813 1887
1814 info->SetExpression(index, *num); 1888 info->SetExpression(index, *num);
1815 } 1889 }
1816 } 1890 }
1817 } 1891 }
1818 #endif 1892 #endif
1819 1893
1820 1894
1821 static const char* TraceValueType(bool is_smi, bool is_native = false) { 1895 static const char* TraceValueType(bool is_smi) {
1822 if (is_native) { 1896 if (is_smi) {
1823 return "native";
1824 } else if (is_smi) {
1825 return "smi"; 1897 return "smi";
1826 } 1898 }
1827 1899
1828 return "heap number"; 1900 return "heap number";
1829 } 1901 }
1830 1902
1831 1903
1832 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, 1904 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
1833 int object_index, 1905 int object_index,
1834 int field_index) { 1906 int field_index) {
(...skipping 10 matching lines...) Expand all
1845 case Translation::CONSTRUCT_STUB_FRAME: 1917 case Translation::CONSTRUCT_STUB_FRAME:
1846 case Translation::GETTER_STUB_FRAME: 1918 case Translation::GETTER_STUB_FRAME:
1847 case Translation::SETTER_STUB_FRAME: 1919 case Translation::SETTER_STUB_FRAME:
1848 case Translation::COMPILED_STUB_FRAME: 1920 case Translation::COMPILED_STUB_FRAME:
1849 UNREACHABLE(); 1921 UNREACHABLE();
1850 return; 1922 return;
1851 1923
1852 case Translation::REGISTER: { 1924 case Translation::REGISTER: {
1853 int input_reg = iterator->Next(); 1925 int input_reg = iterator->Next();
1854 intptr_t input_value = input_->GetRegister(input_reg); 1926 intptr_t input_value = input_->GetRegister(input_reg);
1855 if (trace_) { 1927 if (trace_scope_ != NULL) {
1856 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 1928 PrintF(trace_scope_->file(),
1929 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1857 reinterpret_cast<intptr_t>(object_slot), 1930 reinterpret_cast<intptr_t>(object_slot),
1858 field_index); 1931 field_index);
1859 PrintF("0x%08" V8PRIxPTR " ; %s ", input_value, 1932 PrintF(trace_scope_->file(),
1933 "0x%08" V8PRIxPTR " ; %s ", input_value,
1860 converter.NameOfCPURegister(input_reg)); 1934 converter.NameOfCPURegister(input_reg));
1861 reinterpret_cast<Object*>(input_value)->ShortPrint(); 1935 reinterpret_cast<Object*>(input_value)->ShortPrint(
1862 PrintF("\n"); 1936 trace_scope_->file());
1937 PrintF(trace_scope_->file(),
1938 "\n");
1863 } 1939 }
1864 AddObjectTaggedValue(input_value); 1940 AddObjectTaggedValue(input_value);
1865 return; 1941 return;
1866 } 1942 }
1867 1943
1868 case Translation::INT32_REGISTER: { 1944 case Translation::INT32_REGISTER: {
1869 int input_reg = iterator->Next(); 1945 int input_reg = iterator->Next();
1870 intptr_t value = input_->GetRegister(input_reg); 1946 intptr_t value = input_->GetRegister(input_reg);
1871 bool is_smi = Smi::IsValid(value); 1947 bool is_smi = Smi::IsValid(value);
1872 if (trace_) { 1948 if (trace_scope_ != NULL) {
1873 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 1949 PrintF(trace_scope_->file(),
1950 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1874 reinterpret_cast<intptr_t>(object_slot), 1951 reinterpret_cast<intptr_t>(object_slot),
1875 field_index); 1952 field_index);
1876 PrintF("%" V8PRIdPTR " ; %s (%s)\n", value, 1953 PrintF(trace_scope_->file(),
1954 "%" V8PRIdPTR " ; %s (%s)\n", value,
1877 converter.NameOfCPURegister(input_reg), 1955 converter.NameOfCPURegister(input_reg),
1878 TraceValueType(is_smi)); 1956 TraceValueType(is_smi));
1879 } 1957 }
1880 if (is_smi) { 1958 if (is_smi) {
1881 intptr_t tagged_value = 1959 intptr_t tagged_value =
1882 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 1960 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1883 AddObjectTaggedValue(tagged_value); 1961 AddObjectTaggedValue(tagged_value);
1884 } else { 1962 } else {
1885 double double_value = static_cast<double>(static_cast<int32_t>(value)); 1963 double double_value = static_cast<double>(static_cast<int32_t>(value));
1886 AddObjectDoubleValue(double_value); 1964 AddObjectDoubleValue(double_value);
1887 } 1965 }
1888 return; 1966 return;
1889 } 1967 }
1890 1968
1891 case Translation::UINT32_REGISTER: { 1969 case Translation::UINT32_REGISTER: {
1892 int input_reg = iterator->Next(); 1970 int input_reg = iterator->Next();
1893 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); 1971 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
1894 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); 1972 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
1895 if (trace_) { 1973 if (trace_scope_ != NULL) {
1896 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 1974 PrintF(trace_scope_->file(),
1975 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1897 reinterpret_cast<intptr_t>(object_slot), 1976 reinterpret_cast<intptr_t>(object_slot),
1898 field_index); 1977 field_index);
1899 PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value, 1978 PrintF(trace_scope_->file(),
1979 "%" V8PRIdPTR " ; uint %s (%s)\n", value,
1900 converter.NameOfCPURegister(input_reg), 1980 converter.NameOfCPURegister(input_reg),
1901 TraceValueType(is_smi)); 1981 TraceValueType(is_smi));
1902 } 1982 }
1903 if (is_smi) { 1983 if (is_smi) {
1904 intptr_t tagged_value = 1984 intptr_t tagged_value =
1905 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 1985 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1906 AddObjectTaggedValue(tagged_value); 1986 AddObjectTaggedValue(tagged_value);
1907 } else { 1987 } else {
1908 double double_value = static_cast<double>(static_cast<uint32_t>(value)); 1988 double double_value = static_cast<double>(static_cast<uint32_t>(value));
1909 AddObjectDoubleValue(double_value); 1989 AddObjectDoubleValue(double_value);
1910 } 1990 }
1911 return; 1991 return;
1912 } 1992 }
1913 1993
1914 case Translation::DOUBLE_REGISTER: { 1994 case Translation::DOUBLE_REGISTER: {
1915 int input_reg = iterator->Next(); 1995 int input_reg = iterator->Next();
1916 double value = input_->GetDoubleRegister(input_reg); 1996 double value = input_->GetDoubleRegister(input_reg);
1917 if (trace_) { 1997 if (trace_scope_ != NULL) {
1918 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 1998 PrintF(trace_scope_->file(),
1999 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1919 reinterpret_cast<intptr_t>(object_slot), 2000 reinterpret_cast<intptr_t>(object_slot),
1920 field_index); 2001 field_index);
1921 PrintF("%e ; %s\n", value, 2002 PrintF(trace_scope_->file(),
2003 "%e ; %s\n", value,
1922 DoubleRegister::AllocationIndexToString(input_reg)); 2004 DoubleRegister::AllocationIndexToString(input_reg));
1923 } 2005 }
1924 AddObjectDoubleValue(value); 2006 AddObjectDoubleValue(value);
1925 return; 2007 return;
1926 } 2008 }
1927 2009
1928 case Translation::STACK_SLOT: { 2010 case Translation::STACK_SLOT: {
1929 int input_slot_index = iterator->Next(); 2011 int input_slot_index = iterator->Next();
1930 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2012 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1931 intptr_t input_value = input_->GetFrameSlot(input_offset); 2013 intptr_t input_value = input_->GetFrameSlot(input_offset);
1932 if (trace_) { 2014 if (trace_scope_ != NULL) {
1933 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2015 PrintF(trace_scope_->file(),
2016 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1934 reinterpret_cast<intptr_t>(object_slot), 2017 reinterpret_cast<intptr_t>(object_slot),
1935 field_index); 2018 field_index);
1936 PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); 2019 PrintF(trace_scope_->file(),
1937 reinterpret_cast<Object*>(input_value)->ShortPrint(); 2020 "0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset);
1938 PrintF("\n"); 2021 reinterpret_cast<Object*>(input_value)->ShortPrint(
2022 trace_scope_->file());
2023 PrintF(trace_scope_->file(),
2024 "\n");
1939 } 2025 }
1940 AddObjectTaggedValue(input_value); 2026 AddObjectTaggedValue(input_value);
1941 return; 2027 return;
1942 } 2028 }
1943 2029
1944 case Translation::INT32_STACK_SLOT: { 2030 case Translation::INT32_STACK_SLOT: {
1945 int input_slot_index = iterator->Next(); 2031 int input_slot_index = iterator->Next();
1946 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2032 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1947 intptr_t value = input_->GetFrameSlot(input_offset); 2033 intptr_t value = input_->GetFrameSlot(input_offset);
1948 bool is_smi = Smi::IsValid(value); 2034 bool is_smi = Smi::IsValid(value);
1949 if (trace_) { 2035 if (trace_scope_ != NULL) {
1950 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2036 PrintF(trace_scope_->file(),
2037 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1951 reinterpret_cast<intptr_t>(object_slot), 2038 reinterpret_cast<intptr_t>(object_slot),
1952 field_index); 2039 field_index);
1953 PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n", 2040 PrintF(trace_scope_->file(),
2041 "%" V8PRIdPTR " ; [sp + %d] (%s)\n",
1954 value, input_offset, TraceValueType(is_smi)); 2042 value, input_offset, TraceValueType(is_smi));
1955 } 2043 }
1956 if (is_smi) { 2044 if (is_smi) {
1957 intptr_t tagged_value = 2045 intptr_t tagged_value =
1958 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2046 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1959 AddObjectTaggedValue(tagged_value); 2047 AddObjectTaggedValue(tagged_value);
1960 } else { 2048 } else {
1961 double double_value = static_cast<double>(static_cast<int32_t>(value)); 2049 double double_value = static_cast<double>(static_cast<int32_t>(value));
1962 AddObjectDoubleValue(double_value); 2050 AddObjectDoubleValue(double_value);
1963 } 2051 }
1964 return; 2052 return;
1965 } 2053 }
1966 2054
1967 case Translation::UINT32_STACK_SLOT: { 2055 case Translation::UINT32_STACK_SLOT: {
1968 int input_slot_index = iterator->Next(); 2056 int input_slot_index = iterator->Next();
1969 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2057 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1970 uintptr_t value = 2058 uintptr_t value =
1971 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); 2059 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
1972 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); 2060 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
1973 if (trace_) { 2061 if (trace_scope_ != NULL) {
1974 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2062 PrintF(trace_scope_->file(),
2063 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1975 reinterpret_cast<intptr_t>(object_slot), 2064 reinterpret_cast<intptr_t>(object_slot),
1976 field_index); 2065 field_index);
1977 PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", 2066 PrintF(trace_scope_->file(),
2067 "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
1978 value, input_offset, TraceValueType(is_smi)); 2068 value, input_offset, TraceValueType(is_smi));
1979 } 2069 }
1980 if (is_smi) { 2070 if (is_smi) {
1981 intptr_t tagged_value = 2071 intptr_t tagged_value =
1982 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2072 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
1983 AddObjectTaggedValue(tagged_value); 2073 AddObjectTaggedValue(tagged_value);
1984 } else { 2074 } else {
1985 double double_value = static_cast<double>(static_cast<uint32_t>(value)); 2075 double double_value = static_cast<double>(static_cast<uint32_t>(value));
1986 AddObjectDoubleValue(double_value); 2076 AddObjectDoubleValue(double_value);
1987 } 2077 }
1988 return; 2078 return;
1989 } 2079 }
1990 2080
1991 case Translation::DOUBLE_STACK_SLOT: { 2081 case Translation::DOUBLE_STACK_SLOT: {
1992 int input_slot_index = iterator->Next(); 2082 int input_slot_index = iterator->Next();
1993 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2083 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
1994 double value = input_->GetDoubleFrameSlot(input_offset); 2084 double value = input_->GetDoubleFrameSlot(input_offset);
1995 if (trace_) { 2085 if (trace_scope_ != NULL) {
1996 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2086 PrintF(trace_scope_->file(),
2087 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
1997 reinterpret_cast<intptr_t>(object_slot), 2088 reinterpret_cast<intptr_t>(object_slot),
1998 field_index); 2089 field_index);
1999 PrintF("%e ; [sp + %d]\n", value, input_offset); 2090 PrintF(trace_scope_->file(),
2091 "%e ; [sp + %d]\n", value, input_offset);
2000 } 2092 }
2001 AddObjectDoubleValue(value); 2093 AddObjectDoubleValue(value);
2002 return; 2094 return;
2003 } 2095 }
2004 2096
2005 case Translation::LITERAL: { 2097 case Translation::LITERAL: {
2006 Object* literal = ComputeLiteral(iterator->Next()); 2098 Object* literal = ComputeLiteral(iterator->Next());
2007 if (trace_) { 2099 if (trace_scope_ != NULL) {
2008 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2100 PrintF(trace_scope_->file(),
2101 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2009 reinterpret_cast<intptr_t>(object_slot), 2102 reinterpret_cast<intptr_t>(object_slot),
2010 field_index); 2103 field_index);
2011 literal->ShortPrint(); 2104 literal->ShortPrint(trace_scope_->file());
2012 PrintF(" ; literal\n"); 2105 PrintF(trace_scope_->file(),
2106 " ; literal\n");
2013 } 2107 }
2014 intptr_t value = reinterpret_cast<intptr_t>(literal); 2108 intptr_t value = reinterpret_cast<intptr_t>(literal);
2015 AddObjectTaggedValue(value); 2109 AddObjectTaggedValue(value);
2016 return; 2110 return;
2017 } 2111 }
2018 2112
2019 case Translation::DUPLICATED_OBJECT: { 2113 case Translation::DUPLICATED_OBJECT: {
2020 int object_index = iterator->Next(); 2114 int object_index = iterator->Next();
2021 if (trace_) { 2115 if (trace_scope_ != NULL) {
2022 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", 2116 PrintF(trace_scope_->file(),
2117 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2023 reinterpret_cast<intptr_t>(object_slot), 2118 reinterpret_cast<intptr_t>(object_slot),
2024 field_index); 2119 field_index);
2025 isolate_->heap()->arguments_marker()->ShortPrint(); 2120 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2026 PrintF(" ; duplicate of object #%d\n", object_index); 2121 PrintF(trace_scope_->file(),
2122 " ; duplicate of object #%d\n", object_index);
2027 } 2123 }
2028 // Use the materialization marker value as a sentinel and fill in 2124 // Use the materialization marker value as a sentinel and fill in
2029 // the object after the deoptimized frame is built. 2125 // the object after the deoptimized frame is built.
2030 intptr_t value = reinterpret_cast<intptr_t>( 2126 intptr_t value = reinterpret_cast<intptr_t>(
2031 isolate_->heap()->arguments_marker()); 2127 isolate_->heap()->arguments_marker());
2032 AddObjectDuplication(0, object_index); 2128 AddObjectDuplication(0, object_index);
2033 AddObjectTaggedValue(value); 2129 AddObjectTaggedValue(value);
2034 return; 2130 return;
2035 } 2131 }
2036 2132
2037 case Translation::ARGUMENTS_OBJECT: 2133 case Translation::ARGUMENTS_OBJECT:
2038 case Translation::CAPTURED_OBJECT: { 2134 case Translation::CAPTURED_OBJECT: {
2039 int length = iterator->Next(); 2135 int length = iterator->Next();
2040 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; 2136 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2041 if (trace_) { 2137 if (trace_scope_ != NULL) {
2042 PrintF(" nested @0x%08" V8PRIxPTR ": [field #%d] <- ", 2138 PrintF(trace_scope_->file(),
2139 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2043 reinterpret_cast<intptr_t>(object_slot), 2140 reinterpret_cast<intptr_t>(object_slot),
2044 field_index); 2141 field_index);
2045 isolate_->heap()->arguments_marker()->ShortPrint(); 2142 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2046 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); 2143 PrintF(trace_scope_->file(),
2144 " ; object (length = %d, is_args = %d)\n", length, is_args);
2047 } 2145 }
2048 // Use the materialization marker value as a sentinel and fill in 2146 // Use the materialization marker value as a sentinel and fill in
2049 // the object after the deoptimized frame is built. 2147 // the object after the deoptimized frame is built.
2050 intptr_t value = reinterpret_cast<intptr_t>( 2148 intptr_t value = reinterpret_cast<intptr_t>(
2051 isolate_->heap()->arguments_marker()); 2149 isolate_->heap()->arguments_marker());
2052 AddObjectStart(0, length, is_args); 2150 AddObjectStart(0, length, is_args);
2053 AddObjectTaggedValue(value); 2151 AddObjectTaggedValue(value);
2054 // We save the object values on the side and materialize the actual 2152 // We save the object values on the side and materialize the actual
2055 // object after the deoptimized frame is built. 2153 // object after the deoptimized frame is built.
2056 int object_index = deferred_objects_.length() - 1; 2154 int object_index = deferred_objects_.length() - 1;
2057 for (int i = 0; i < length; i++) { 2155 for (int i = 0; i < length; i++) {
2058 DoTranslateObject(iterator, object_index, i); 2156 DoTranslateObject(iterator, object_index, i);
2059 } 2157 }
2060 return; 2158 return;
2061 } 2159 }
2062 } 2160 }
2063 } 2161 }
2064 2162
2065 2163
2066 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 2164 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
2067 int frame_index, 2165 int frame_index,
2068 unsigned output_offset, 2166 unsigned output_offset) {
2069 DeoptimizerTranslatedValueType value_type) {
2070 disasm::NameConverter converter; 2167 disasm::NameConverter converter;
2071 // A GC-safe temporary placeholder that we can put in the output frame. 2168 // A GC-safe temporary placeholder that we can put in the output frame.
2072 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 2169 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
2073 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE;
2074 2170
2075 Translation::Opcode opcode = 2171 Translation::Opcode opcode =
2076 static_cast<Translation::Opcode>(iterator->Next()); 2172 static_cast<Translation::Opcode>(iterator->Next());
2077 2173
2078 switch (opcode) { 2174 switch (opcode) {
2079 case Translation::BEGIN: 2175 case Translation::BEGIN:
2080 case Translation::JS_FRAME: 2176 case Translation::JS_FRAME:
2081 case Translation::ARGUMENTS_ADAPTOR_FRAME: 2177 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2082 case Translation::CONSTRUCT_STUB_FRAME: 2178 case Translation::CONSTRUCT_STUB_FRAME:
2083 case Translation::GETTER_STUB_FRAME: 2179 case Translation::GETTER_STUB_FRAME:
2084 case Translation::SETTER_STUB_FRAME: 2180 case Translation::SETTER_STUB_FRAME:
2085 case Translation::COMPILED_STUB_FRAME: 2181 case Translation::COMPILED_STUB_FRAME:
2086 UNREACHABLE(); 2182 UNREACHABLE();
2087 return; 2183 return;
2088 2184
2089 case Translation::REGISTER: { 2185 case Translation::REGISTER: {
2090 int input_reg = iterator->Next(); 2186 int input_reg = iterator->Next();
2091 intptr_t input_value = input_->GetRegister(input_reg); 2187 intptr_t input_value = input_->GetRegister(input_reg);
2092 if (trace_) { 2188 if (trace_scope_ != NULL) {
2093 PrintF( 2189 PrintF(
2190 trace_scope_->file(),
2094 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", 2191 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
2095 output_[frame_index]->GetTop() + output_offset, 2192 output_[frame_index]->GetTop() + output_offset,
2096 output_offset, 2193 output_offset,
2097 input_value, 2194 input_value,
2098 converter.NameOfCPURegister(input_reg)); 2195 converter.NameOfCPURegister(input_reg));
2099 reinterpret_cast<Object*>(input_value)->ShortPrint(); 2196 reinterpret_cast<Object*>(input_value)->ShortPrint(
2100 PrintF("\n"); 2197 trace_scope_->file());
2198 PrintF(trace_scope_->file(), "\n");
2101 } 2199 }
2102 output_[frame_index]->SetFrameSlot(output_offset, input_value); 2200 output_[frame_index]->SetFrameSlot(output_offset, input_value);
2103 return; 2201 return;
2104 } 2202 }
2105 2203
2106 case Translation::INT32_REGISTER: { 2204 case Translation::INT32_REGISTER: {
2107 int input_reg = iterator->Next(); 2205 int input_reg = iterator->Next();
2108 intptr_t value = input_->GetRegister(input_reg); 2206 intptr_t value = input_->GetRegister(input_reg);
2109 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && 2207 bool is_smi = Smi::IsValid(value);
2110 Smi::IsValid(value); 2208 if (trace_scope_ != NULL) {
2111 if (trace_) {
2112 PrintF( 2209 PrintF(
2210 trace_scope_->file(),
2113 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", 2211 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
2114 output_[frame_index]->GetTop() + output_offset, 2212 output_[frame_index]->GetTop() + output_offset,
2115 output_offset, 2213 output_offset,
2116 value, 2214 value,
2117 converter.NameOfCPURegister(input_reg), 2215 converter.NameOfCPURegister(input_reg),
2118 TraceValueType(is_smi, is_native)); 2216 TraceValueType(is_smi));
2119 } 2217 }
2120 if (is_smi) { 2218 if (is_smi) {
2121 intptr_t tagged_value = 2219 intptr_t tagged_value =
2122 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2220 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2123 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 2221 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2124 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2125 output_[frame_index]->SetFrameSlot(output_offset, value);
2126 } else { 2222 } else {
2127 // We save the untagged value on the side and store a GC-safe 2223 // We save the untagged value on the side and store a GC-safe
2128 // temporary placeholder in the frame. 2224 // temporary placeholder in the frame.
2129 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
2130 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 2225 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2131 static_cast<double>(static_cast<int32_t>(value))); 2226 static_cast<double>(static_cast<int32_t>(value)));
2132 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2227 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2133 } 2228 }
2134 return; 2229 return;
2135 } 2230 }
2136 2231
2137 case Translation::UINT32_REGISTER: { 2232 case Translation::UINT32_REGISTER: {
2138 int input_reg = iterator->Next(); 2233 int input_reg = iterator->Next();
2139 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); 2234 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
2140 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && 2235 bool is_smi = value <= static_cast<uintptr_t>(Smi::kMaxValue);
2141 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); 2236 if (trace_scope_ != NULL) {
2142 if (trace_) {
2143 PrintF( 2237 PrintF(
2238 trace_scope_->file(),
2144 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR 2239 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
2145 " ; uint %s (%s)\n", 2240 " ; uint %s (%s)\n",
2146 output_[frame_index]->GetTop() + output_offset, 2241 output_[frame_index]->GetTop() + output_offset,
2147 output_offset, 2242 output_offset,
2148 value, 2243 value,
2149 converter.NameOfCPURegister(input_reg), 2244 converter.NameOfCPURegister(input_reg),
2150 TraceValueType(is_smi, is_native)); 2245 TraceValueType(is_smi));
2151 } 2246 }
2152 if (is_smi) { 2247 if (is_smi) {
2153 intptr_t tagged_value = 2248 intptr_t tagged_value =
2154 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2249 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2155 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 2250 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2156 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2157 output_[frame_index]->SetFrameSlot(output_offset, value);
2158 } else { 2251 } else {
2159 // We save the untagged value on the side and store a GC-safe 2252 // We save the untagged value on the side and store a GC-safe
2160 // temporary placeholder in the frame. 2253 // temporary placeholder in the frame.
2161 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
2162 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 2254 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2163 static_cast<double>(static_cast<uint32_t>(value))); 2255 static_cast<double>(static_cast<uint32_t>(value)));
2164 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2256 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2165 } 2257 }
2166 return; 2258 return;
2167 } 2259 }
2168 2260
2169 case Translation::DOUBLE_REGISTER: { 2261 case Translation::DOUBLE_REGISTER: {
2170 int input_reg = iterator->Next(); 2262 int input_reg = iterator->Next();
2171 double value = input_->GetDoubleRegister(input_reg); 2263 double value = input_->GetDoubleRegister(input_reg);
2172 if (trace_) { 2264 if (trace_scope_ != NULL) {
2173 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", 2265 PrintF(trace_scope_->file(),
2266 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
2174 output_[frame_index]->GetTop() + output_offset, 2267 output_[frame_index]->GetTop() + output_offset,
2175 output_offset, 2268 output_offset,
2176 value, 2269 value,
2177 DoubleRegister::AllocationIndexToString(input_reg)); 2270 DoubleRegister::AllocationIndexToString(input_reg));
2178 } 2271 }
2179 // We save the untagged value on the side and store a GC-safe 2272 // We save the untagged value on the side and store a GC-safe
2180 // temporary placeholder in the frame. 2273 // temporary placeholder in the frame.
2181 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); 2274 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2182 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2275 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2183 return; 2276 return;
2184 } 2277 }
2185 2278
2186 case Translation::STACK_SLOT: { 2279 case Translation::STACK_SLOT: {
2187 int input_slot_index = iterator->Next(); 2280 int input_slot_index = iterator->Next();
2188 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2281 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2189 intptr_t input_value = input_->GetFrameSlot(input_offset); 2282 intptr_t input_value = input_->GetFrameSlot(input_offset);
2190 if (trace_) { 2283 if (trace_scope_ != NULL) {
2191 PrintF(" 0x%08" V8PRIxPTR ": ", 2284 PrintF(trace_scope_->file(),
2285 " 0x%08" V8PRIxPTR ": ",
2192 output_[frame_index]->GetTop() + output_offset); 2286 output_[frame_index]->GetTop() + output_offset);
2193 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", 2287 PrintF(trace_scope_->file(),
2288 "[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
2194 output_offset, 2289 output_offset,
2195 input_value, 2290 input_value,
2196 input_offset); 2291 input_offset);
2197 reinterpret_cast<Object*>(input_value)->ShortPrint(); 2292 reinterpret_cast<Object*>(input_value)->ShortPrint(
2198 PrintF("\n"); 2293 trace_scope_->file());
2294 PrintF(trace_scope_->file(), "\n");
2199 } 2295 }
2200 output_[frame_index]->SetFrameSlot(output_offset, input_value); 2296 output_[frame_index]->SetFrameSlot(output_offset, input_value);
2201 return; 2297 return;
2202 } 2298 }
2203 2299
2204 case Translation::INT32_STACK_SLOT: { 2300 case Translation::INT32_STACK_SLOT: {
2205 int input_slot_index = iterator->Next(); 2301 int input_slot_index = iterator->Next();
2206 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2302 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2207 intptr_t value = input_->GetFrameSlot(input_offset); 2303 intptr_t value = input_->GetFrameSlot(input_offset);
2208 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && 2304 bool is_smi = Smi::IsValid(value);
2209 Smi::IsValid(value); 2305 if (trace_scope_ != NULL) {
2210 if (trace_) { 2306 PrintF(trace_scope_->file(),
2211 PrintF(" 0x%08" V8PRIxPTR ": ", 2307 " 0x%08" V8PRIxPTR ": ",
2212 output_[frame_index]->GetTop() + output_offset); 2308 output_[frame_index]->GetTop() + output_offset);
2213 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", 2309 PrintF(trace_scope_->file(),
2310 "[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n",
2214 output_offset, 2311 output_offset,
2215 value, 2312 value,
2216 input_offset, 2313 input_offset,
2217 TraceValueType(is_smi, is_native)); 2314 TraceValueType(is_smi));
2218 } 2315 }
2219 if (is_smi) { 2316 if (is_smi) {
2220 intptr_t tagged_value = 2317 intptr_t tagged_value =
2221 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2318 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2222 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 2319 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2223 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2224 output_[frame_index]->SetFrameSlot(output_offset, value);
2225 } else { 2320 } else {
2226 // We save the untagged value on the side and store a GC-safe 2321 // We save the untagged value on the side and store a GC-safe
2227 // temporary placeholder in the frame. 2322 // temporary placeholder in the frame.
2228 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
2229 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 2323 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2230 static_cast<double>(static_cast<int32_t>(value))); 2324 static_cast<double>(static_cast<int32_t>(value)));
2231 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2325 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2232 } 2326 }
2233 return; 2327 return;
2234 } 2328 }
2235 2329
2236 case Translation::UINT32_STACK_SLOT: { 2330 case Translation::UINT32_STACK_SLOT: {
2237 int input_slot_index = iterator->Next(); 2331 int input_slot_index = iterator->Next();
2238 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2332 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2239 uintptr_t value = 2333 uintptr_t value =
2240 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); 2334 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
2241 bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && 2335 bool is_smi = value <= static_cast<uintptr_t>(Smi::kMaxValue);
2242 (value <= static_cast<uintptr_t>(Smi::kMaxValue)); 2336 if (trace_scope_ != NULL) {
2243 if (trace_) { 2337 PrintF(trace_scope_->file(),
2244 PrintF(" 0x%08" V8PRIxPTR ": ", 2338 " 0x%08" V8PRIxPTR ": ",
2245 output_[frame_index]->GetTop() + output_offset); 2339 output_[frame_index]->GetTop() + output_offset);
2246 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", 2340 PrintF(trace_scope_->file(),
2341 "[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
2247 output_offset, 2342 output_offset,
2248 value, 2343 value,
2249 input_offset, 2344 input_offset,
2250 TraceValueType(is_smi, is_native)); 2345 TraceValueType(is_smi));
2251 } 2346 }
2252 if (is_smi) { 2347 if (is_smi) {
2253 intptr_t tagged_value = 2348 intptr_t tagged_value =
2254 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 2349 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
2255 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 2350 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
2256 } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) {
2257 output_[frame_index]->SetFrameSlot(output_offset, value);
2258 } else { 2351 } else {
2259 // We save the untagged value on the side and store a GC-safe 2352 // We save the untagged value on the side and store a GC-safe
2260 // temporary placeholder in the frame. 2353 // temporary placeholder in the frame.
2261 ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
2262 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 2354 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2263 static_cast<double>(static_cast<uint32_t>(value))); 2355 static_cast<double>(static_cast<uint32_t>(value)));
2264 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2356 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2265 } 2357 }
2266 return; 2358 return;
2267 } 2359 }
2268 2360
2269 case Translation::DOUBLE_STACK_SLOT: { 2361 case Translation::DOUBLE_STACK_SLOT: {
2270 int input_slot_index = iterator->Next(); 2362 int input_slot_index = iterator->Next();
2271 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); 2363 unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
2272 double value = input_->GetDoubleFrameSlot(input_offset); 2364 double value = input_->GetDoubleFrameSlot(input_offset);
2273 if (trace_) { 2365 if (trace_scope_ != NULL) {
2274 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", 2366 PrintF(trace_scope_->file(),
2367 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
2275 output_[frame_index]->GetTop() + output_offset, 2368 output_[frame_index]->GetTop() + output_offset,
2276 output_offset, 2369 output_offset,
2277 value, 2370 value,
2278 input_offset); 2371 input_offset);
2279 } 2372 }
2280 // We save the untagged value on the side and store a GC-safe 2373 // We save the untagged value on the side and store a GC-safe
2281 // temporary placeholder in the frame. 2374 // temporary placeholder in the frame.
2282 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); 2375 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2283 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 2376 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
2284 return; 2377 return;
2285 } 2378 }
2286 2379
2287 case Translation::LITERAL: { 2380 case Translation::LITERAL: {
2288 Object* literal = ComputeLiteral(iterator->Next()); 2381 Object* literal = ComputeLiteral(iterator->Next());
2289 if (trace_) { 2382 if (trace_scope_ != NULL) {
2290 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 2383 PrintF(trace_scope_->file(),
2384 " 0x%08" V8PRIxPTR ": [top + %d] <- ",
2291 output_[frame_index]->GetTop() + output_offset, 2385 output_[frame_index]->GetTop() + output_offset,
2292 output_offset); 2386 output_offset);
2293 literal->ShortPrint(); 2387 literal->ShortPrint(trace_scope_->file());
2294 PrintF(" ; literal\n"); 2388 PrintF(trace_scope_->file(), " ; literal\n");
2295 } 2389 }
2296 intptr_t value = reinterpret_cast<intptr_t>(literal); 2390 intptr_t value = reinterpret_cast<intptr_t>(literal);
2297 output_[frame_index]->SetFrameSlot(output_offset, value); 2391 output_[frame_index]->SetFrameSlot(output_offset, value);
2298 return; 2392 return;
2299 } 2393 }
2300 2394
2301 case Translation::DUPLICATED_OBJECT: { 2395 case Translation::DUPLICATED_OBJECT: {
2302 int object_index = iterator->Next(); 2396 int object_index = iterator->Next();
2303 if (trace_) { 2397 if (trace_scope_ != NULL) {
2304 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 2398 PrintF(trace_scope_->file(),
2399 " 0x%08" V8PRIxPTR ": [top + %d] <- ",
2305 output_[frame_index]->GetTop() + output_offset, 2400 output_[frame_index]->GetTop() + output_offset,
2306 output_offset); 2401 output_offset);
2307 isolate_->heap()->arguments_marker()->ShortPrint(); 2402 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2308 PrintF(" ; duplicate of object #%d\n", object_index); 2403 PrintF(trace_scope_->file(),
2404 " ; duplicate of object #%d\n", object_index);
2309 } 2405 }
2310 // Use the materialization marker value as a sentinel and fill in 2406 // Use the materialization marker value as a sentinel and fill in
2311 // the object after the deoptimized frame is built. 2407 // the object after the deoptimized frame is built.
2312 intptr_t value = reinterpret_cast<intptr_t>( 2408 intptr_t value = reinterpret_cast<intptr_t>(
2313 isolate_->heap()->arguments_marker()); 2409 isolate_->heap()->arguments_marker());
2314 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset, 2410 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset,
2315 object_index); 2411 object_index);
2316 output_[frame_index]->SetFrameSlot(output_offset, value); 2412 output_[frame_index]->SetFrameSlot(output_offset, value);
2317 return; 2413 return;
2318 } 2414 }
2319 2415
2320 case Translation::ARGUMENTS_OBJECT: 2416 case Translation::ARGUMENTS_OBJECT:
2321 case Translation::CAPTURED_OBJECT: { 2417 case Translation::CAPTURED_OBJECT: {
2322 int length = iterator->Next(); 2418 int length = iterator->Next();
2323 bool is_args = opcode == Translation::ARGUMENTS_OBJECT; 2419 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2324 if (trace_) { 2420 if (trace_scope_ != NULL) {
2325 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 2421 PrintF(trace_scope_->file(),
2422 " 0x%08" V8PRIxPTR ": [top + %d] <- ",
2326 output_[frame_index]->GetTop() + output_offset, 2423 output_[frame_index]->GetTop() + output_offset,
2327 output_offset); 2424 output_offset);
2328 isolate_->heap()->arguments_marker()->ShortPrint(); 2425 isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2329 PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args); 2426 PrintF(trace_scope_->file(),
2427 " ; object (length = %d, is_args = %d)\n", length, is_args);
2330 } 2428 }
2331 // Use the materialization marker value as a sentinel and fill in 2429 // Use the materialization marker value as a sentinel and fill in
2332 // the object after the deoptimized frame is built. 2430 // the object after the deoptimized frame is built.
2333 intptr_t value = reinterpret_cast<intptr_t>( 2431 intptr_t value = reinterpret_cast<intptr_t>(
2334 isolate_->heap()->arguments_marker()); 2432 isolate_->heap()->arguments_marker());
2335 AddObjectStart(output_[frame_index]->GetTop() + output_offset, 2433 AddObjectStart(output_[frame_index]->GetTop() + output_offset,
2336 length, is_args); 2434 length, is_args);
2337 output_[frame_index]->SetFrameSlot(output_offset, value); 2435 output_[frame_index]->SetFrameSlot(output_offset, value);
2338 // We save the object values on the side and materialize the actual 2436 // We save the object values on the side and materialize the actual
2339 // object after the deoptimized frame is built. 2437 // object after the deoptimized frame is built.
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 3046
2949 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 3047 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
2950 v->VisitPointer(BitCast<Object**>(&function_)); 3048 v->VisitPointer(BitCast<Object**>(&function_));
2951 v->VisitPointers(parameters_, parameters_ + parameters_count_); 3049 v->VisitPointers(parameters_, parameters_ + parameters_count_);
2952 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 3050 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
2953 } 3051 }
2954 3052
2955 #endif // ENABLE_DEBUGGER_SUPPORT 3053 #endif // ENABLE_DEBUGGER_SUPPORT
2956 3054
2957 } } // namespace v8::internal 3055 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/disassembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698