OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 int params = descriptor->register_param_count_; | 481 int params = descriptor->register_param_count_; |
482 if (descriptor->stack_parameter_count_ != NULL) { | 482 if (descriptor->stack_parameter_count_ != NULL) { |
483 params++; | 483 params++; |
484 } | 484 } |
485 output_frame->SetRegister(s0.code(), params); | 485 output_frame->SetRegister(s0.code(), params); |
486 output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize); | 486 output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize); |
487 output_frame->SetRegister(s2.code(), handler); | 487 output_frame->SetRegister(s2.code(), handler); |
488 } | 488 } |
489 | 489 |
490 | 490 |
491 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | |
492 int frame_index) { | |
493 Builtins* builtins = isolate_->builtins(); | |
494 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | |
495 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | |
496 unsigned height = iterator->Next(); | |
497 unsigned height_in_bytes = height * kPointerSize; | |
498 if (FLAG_trace_deopt) { | |
499 PrintF(" translating construct stub => height=%d\n", height_in_bytes); | |
500 } | |
501 | |
502 unsigned fixed_frame_size = 8 * kPointerSize; | |
503 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | |
504 | |
505 // Allocate and store the output frame description. | |
506 FrameDescription* output_frame = | |
507 new(output_frame_size) FrameDescription(output_frame_size, function); | |
508 output_frame->SetFrameType(StackFrame::CONSTRUCT); | |
509 | |
510 // Construct stub can not be topmost or bottommost. | |
511 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); | |
512 ASSERT(output_[frame_index] == NULL); | |
513 output_[frame_index] = output_frame; | |
514 | |
515 // The top address of the frame is computed from the previous | |
516 // frame's top and this frame's size. | |
517 uint32_t top_address; | |
518 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | |
519 output_frame->SetTop(top_address); | |
520 | |
521 // Compute the incoming parameter translation. | |
522 int parameter_count = height; | |
523 unsigned output_offset = output_frame_size; | |
524 for (int i = 0; i < parameter_count; ++i) { | |
525 output_offset -= kPointerSize; | |
526 DoTranslateCommand(iterator, frame_index, output_offset); | |
527 } | |
528 | |
529 // Read caller's PC from the previous frame. | |
530 output_offset -= kPointerSize; | |
531 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | |
532 output_frame->SetFrameSlot(output_offset, callers_pc); | |
533 if (FLAG_trace_deopt) { | |
534 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", | |
535 top_address + output_offset, output_offset, callers_pc); | |
536 } | |
537 | |
538 // Read caller's FP from the previous frame, and set this frame's FP. | |
539 output_offset -= kPointerSize; | |
540 intptr_t value = output_[frame_index - 1]->GetFp(); | |
541 output_frame->SetFrameSlot(output_offset, value); | |
542 intptr_t fp_value = top_address + output_offset; | |
543 output_frame->SetFp(fp_value); | |
544 if (trace_) { | |
545 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | |
546 fp_value, output_offset, value); | |
547 } | |
548 | |
549 // The context can be gotten from the previous frame. | |
550 output_offset -= kPointerSize; | |
551 value = output_[frame_index - 1]->GetContext(); | |
552 output_frame->SetFrameSlot(output_offset, value); | |
553 if (trace_) { | |
554 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", | |
555 top_address + output_offset, output_offset, value); | |
556 } | |
557 | |
558 // A marker value is used in place of the function. | |
559 output_offset -= kPointerSize; | |
560 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); | |
561 output_frame->SetFrameSlot(output_offset, value); | |
562 if (trace_) { | |
563 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", | |
564 top_address + output_offset, output_offset, value); | |
565 } | |
566 | |
567 // The output frame reflects a JSConstructStubGeneric frame. | |
568 output_offset -= kPointerSize; | |
569 value = reinterpret_cast<intptr_t>(construct_stub); | |
570 output_frame->SetFrameSlot(output_offset, value); | |
571 if (trace_) { | |
572 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n", | |
573 top_address + output_offset, output_offset, value); | |
574 } | |
575 | |
576 // Number of incoming arguments. | |
577 output_offset -= kPointerSize; | |
578 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); | |
579 output_frame->SetFrameSlot(output_offset, value); | |
580 if (trace_) { | |
581 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", | |
582 top_address + output_offset, output_offset, value, height - 1); | |
583 } | |
584 | |
585 // Constructor function being invoked by the stub. | |
586 output_offset -= kPointerSize; | |
587 value = reinterpret_cast<intptr_t>(function); | |
588 output_frame->SetFrameSlot(output_offset, value); | |
589 if (trace_) { | |
590 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n", | |
591 top_address + output_offset, output_offset, value); | |
592 } | |
593 | |
594 // The newly allocated object was passed as receiver in the artificial | |
595 // constructor stub environment created by HEnvironment::CopyForInlining(). | |
596 output_offset -= kPointerSize; | |
597 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); | |
598 output_frame->SetFrameSlot(output_offset, value); | |
599 if (trace_) { | |
600 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", | |
601 top_address + output_offset, output_offset, value); | |
602 } | |
603 | |
604 ASSERT(0 == output_offset); | |
605 | |
606 uint32_t pc = reinterpret_cast<uint32_t>( | |
607 construct_stub->instruction_start() + | |
608 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | |
609 output_frame->SetPc(pc); | |
610 } | |
611 | |
612 | |
613 // This code is very similar to ia32/arm code, but relies on register names | 491 // This code is very similar to ia32/arm code, but relies on register names |
614 // (fp, sp) and how the frame is laid out. | 492 // (fp, sp) and how the frame is laid out. |
615 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 493 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
616 int frame_index) { | 494 int frame_index) { |
617 // Read the ast node id, function, and frame height for this output frame. | 495 // Read the ast node id, function, and frame height for this output frame. |
618 BailoutId node_id = BailoutId(iterator->Next()); | 496 BailoutId node_id = BailoutId(iterator->Next()); |
619 JSFunction* function; | 497 JSFunction* function; |
620 if (frame_index != 0) { | 498 if (frame_index != 0) { |
621 function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 499 function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
622 } else { | 500 } else { |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 } | 946 } |
1069 | 947 |
1070 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | 948 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
1071 count() * table_entry_size_); | 949 count() * table_entry_size_); |
1072 } | 950 } |
1073 | 951 |
1074 #undef __ | 952 #undef __ |
1075 | 953 |
1076 | 954 |
1077 } } // namespace v8::internal | 955 } } // namespace v8::internal |
OLD | NEW |