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

Side by Side Diff: src/x64/deoptimizer-x64.cc

Issue 12374044: Unify deoptimizer for accessor and arguments frames. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months 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/mips/deoptimizer-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 if (FLAG_trace_osr) { 341 if (FLAG_trace_osr) {
342 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 342 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
343 ok ? "finished" : "aborted", 343 ok ? "finished" : "aborted",
344 reinterpret_cast<intptr_t>(function_)); 344 reinterpret_cast<intptr_t>(function_));
345 function_->PrintName(); 345 function_->PrintName();
346 PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc()); 346 PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc());
347 } 347 }
348 } 348 }
349 349
350 350
351 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
352 int frame_index) {
353 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
354 unsigned height = iterator->Next();
355 unsigned height_in_bytes = height * kPointerSize;
356 if (trace_) {
357 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
358 }
359
360 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
361 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
362
363 // Allocate and store the output frame description.
364 FrameDescription* output_frame =
365 new(output_frame_size) FrameDescription(output_frame_size, function);
366 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
367
368 // Arguments adaptor can not be topmost or bottommost.
369 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
370 ASSERT(output_[frame_index] == NULL);
371 output_[frame_index] = output_frame;
372
373 // The top address of the frame is computed from the previous
374 // frame's top and this frame's size.
375 intptr_t top_address;
376 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
377 output_frame->SetTop(top_address);
378
379 // Compute the incoming parameter translation.
380 int parameter_count = height;
381 unsigned output_offset = output_frame_size;
382 for (int i = 0; i < parameter_count; ++i) {
383 output_offset -= kPointerSize;
384 DoTranslateCommand(iterator, frame_index, output_offset);
385 }
386
387 // Read caller's PC from the previous frame.
388 output_offset -= kPointerSize;
389 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
390 output_frame->SetFrameSlot(output_offset, callers_pc);
391 if (trace_) {
392 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
393 V8PRIxPTR " ; caller's pc\n",
394 top_address + output_offset, output_offset, callers_pc);
395 }
396
397 // Read caller's FP from the previous frame, and set this frame's FP.
398 output_offset -= kPointerSize;
399 intptr_t value = output_[frame_index - 1]->GetFp();
400 output_frame->SetFrameSlot(output_offset, value);
401 intptr_t fp_value = top_address + output_offset;
402 output_frame->SetFp(fp_value);
403 if (trace_) {
404 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
405 V8PRIxPTR " ; caller's fp\n",
406 fp_value, output_offset, value);
407 }
408
409 // A marker value is used in place of the context.
410 output_offset -= kPointerSize;
411 intptr_t context = reinterpret_cast<intptr_t>(
412 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
413 output_frame->SetFrameSlot(output_offset, context);
414 if (trace_) {
415 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
416 V8PRIxPTR " ; context (adaptor sentinel)\n",
417 top_address + output_offset, output_offset, context);
418 }
419
420 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
421 output_offset -= kPointerSize;
422 value = reinterpret_cast<intptr_t>(function);
423 output_frame->SetFrameSlot(output_offset, value);
424 if (trace_) {
425 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
426 V8PRIxPTR " ; function\n",
427 top_address + output_offset, output_offset, value);
428 }
429
430 // Number of incoming arguments.
431 output_offset -= kPointerSize;
432 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
433 output_frame->SetFrameSlot(output_offset, value);
434 if (trace_) {
435 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
436 V8PRIxPTR " ; argc (%d)\n",
437 top_address + output_offset, output_offset, value, height - 1);
438 }
439
440 ASSERT(0 == output_offset);
441
442 Builtins* builtins = isolate_->builtins();
443 Code* adaptor_trampoline =
444 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
445 intptr_t pc_value = reinterpret_cast<intptr_t>(
446 adaptor_trampoline->instruction_start() +
447 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
448 output_frame->SetPc(pc_value);
449 }
450
451
452 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, 351 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
453 int frame_index) { 352 int frame_index) {
454 // 353 //
455 // FROM TO 354 // FROM TO
456 // | .... | | .... | 355 // | .... | | .... |
457 // +-------------------------+ +-------------------------+ 356 // +-------------------------+ +-------------------------+
458 // | JSFunction continuation | | JSFunction continuation | 357 // | JSFunction continuation | | JSFunction continuation |
459 // +-------------------------+ +-------------------------+ 358 // +-------------------------+ +-------------------------+
460 // | | saved frame (rbp) | | saved frame (rbp) | 359 // | | saved frame (rbp) | | saved frame (rbp) |
461 // | +=========================+<-rbp +=========================+<-rbp 360 // | +=========================+<-rbp +=========================+<-rbp
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 648
750 ASSERT(0 == output_offset); 649 ASSERT(0 == output_offset);
751 650
752 intptr_t pc = reinterpret_cast<intptr_t>( 651 intptr_t pc = reinterpret_cast<intptr_t>(
753 construct_stub->instruction_start() + 652 construct_stub->instruction_start() +
754 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 653 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
755 output_frame->SetPc(pc); 654 output_frame->SetPc(pc);
756 } 655 }
757 656
758 657
759 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
760 int frame_index,
761 bool is_setter_stub_frame) {
762 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
763 // The receiver (and the implicit return value, if any) are expected in
764 // registers by the LoadIC/StoreIC, so they don't belong to the output stack
765 // frame. This means that we have to use a height of 0.
766 unsigned height = 0;
767 unsigned height_in_bytes = height * kPointerSize;
768 const char* kind = is_setter_stub_frame ? "setter" : "getter";
769 if (trace_) {
770 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
771 }
772
773 // We need 1 stack entry for the return address + 4 stack entries from
774 // StackFrame::INTERNAL (FP, context, frame type, code object, see
775 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional
776 // entry for the implicit return value, see
777 // StoreStubCompiler::CompileStoreViaSetter.
778 unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0);
779 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
780 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
781
782 // Allocate and store the output frame description.
783 FrameDescription* output_frame =
784 new(output_frame_size) FrameDescription(output_frame_size, accessor);
785 output_frame->SetFrameType(StackFrame::INTERNAL);
786
787 // A frame for an accessor stub can not be the topmost or bottommost one.
788 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
789 ASSERT(output_[frame_index] == NULL);
790 output_[frame_index] = output_frame;
791
792 // The top address of the frame is computed from the previous frame's top and
793 // this frame's size.
794 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
795 output_frame->SetTop(top_address);
796
797 unsigned output_offset = output_frame_size;
798
799 // Read caller's PC from the previous frame.
800 output_offset -= kPointerSize;
801 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
802 output_frame->SetFrameSlot(output_offset, callers_pc);
803 if (trace_) {
804 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
805 " ; caller's pc\n",
806 top_address + output_offset, output_offset, callers_pc);
807 }
808
809 // Read caller's FP from the previous frame, and set this frame's FP.
810 output_offset -= kPointerSize;
811 intptr_t value = output_[frame_index - 1]->GetFp();
812 output_frame->SetFrameSlot(output_offset, value);
813 intptr_t fp_value = top_address + output_offset;
814 output_frame->SetFp(fp_value);
815 if (trace_) {
816 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
817 " ; caller's fp\n",
818 fp_value, output_offset, value);
819 }
820
821 // The context can be gotten from the previous frame.
822 output_offset -= kPointerSize;
823 value = output_[frame_index - 1]->GetContext();
824 output_frame->SetFrameSlot(output_offset, value);
825 if (trace_) {
826 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
827 " ; context\n",
828 top_address + output_offset, output_offset, value);
829 }
830
831 // A marker value is used in place of the function.
832 output_offset -= kPointerSize;
833 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
834 output_frame->SetFrameSlot(output_offset, value);
835 if (trace_) {
836 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
837 " ; function (%s sentinel)\n",
838 top_address + output_offset, output_offset, value, kind);
839 }
840
841 // Get Code object from accessor stub.
842 output_offset -= kPointerSize;
843 Builtins::Name name = is_setter_stub_frame ?
844 Builtins::kStoreIC_Setter_ForDeopt :
845 Builtins::kLoadIC_Getter_ForDeopt;
846 Code* accessor_stub = isolate_->builtins()->builtin(name);
847 value = reinterpret_cast<intptr_t>(accessor_stub);
848 output_frame->SetFrameSlot(output_offset, value);
849 if (trace_) {
850 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
851 " ; code object\n",
852 top_address + output_offset, output_offset, value);
853 }
854
855 // Skip receiver.
856 Translation::Opcode opcode =
857 static_cast<Translation::Opcode>(iterator->Next());
858 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
859
860 if (is_setter_stub_frame) {
861 // The implicit return value was part of the artificial setter stub
862 // environment.
863 output_offset -= kPointerSize;
864 DoTranslateCommand(iterator, frame_index, output_offset);
865 }
866
867 ASSERT(0 == output_offset);
868
869 Smi* offset = is_setter_stub_frame ?
870 isolate_->heap()->setter_stub_deopt_pc_offset() :
871 isolate_->heap()->getter_stub_deopt_pc_offset();
872 intptr_t pc = reinterpret_cast<intptr_t>(
873 accessor_stub->instruction_start() + offset->value());
874 output_frame->SetPc(pc);
875 }
876
877
878 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 658 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
879 int frame_index) { 659 int frame_index) {
880 BailoutId node_id = BailoutId(iterator->Next()); 660 BailoutId node_id = BailoutId(iterator->Next());
881 JSFunction* function; 661 JSFunction* function;
882 if (frame_index != 0) { 662 if (frame_index != 0) {
883 function = JSFunction::cast(ComputeLiteral(iterator->Next())); 663 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
884 } else { 664 } else {
885 int closure_id = iterator->Next(); 665 int closure_id = iterator->Next();
886 USE(closure_id); 666 USE(closure_id);
887 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 667 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 } 1067 }
1288 __ bind(&done); 1068 __ bind(&done);
1289 } 1069 }
1290 1070
1291 #undef __ 1071 #undef __
1292 1072
1293 1073
1294 } } // namespace v8::internal 1074 } } // namespace v8::internal
1295 1075
1296 #endif // V8_TARGET_ARCH_X64 1076 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips/deoptimizer-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698