| 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 |