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

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

Issue 9304001: Implement inlining of constructor calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed moar comments by Vyacheslav Egorov. Created 8 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/ia32/builtins-ia32.cc ('k') | src/ia32/full-codegen-ia32.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 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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 439 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
440 int frame_index) { 440 int frame_index) {
441 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 441 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
442 unsigned height = iterator->Next(); 442 unsigned height = iterator->Next();
443 unsigned height_in_bytes = height * kPointerSize; 443 unsigned height_in_bytes = height * kPointerSize;
444 if (FLAG_trace_deopt) { 444 if (FLAG_trace_deopt) {
445 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); 445 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
446 } 446 }
447 447
448 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 448 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
449 unsigned input_frame_size = input_->GetFrameSize();
450 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 449 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
451 450
452 // Allocate and store the output frame description. 451 // Allocate and store the output frame description.
453 FrameDescription* output_frame = 452 FrameDescription* output_frame =
454 new(output_frame_size) FrameDescription(output_frame_size, function); 453 new(output_frame_size) FrameDescription(output_frame_size, function);
455 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 454 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
456 455
457 // Arguments adaptor can not be topmost or bottommost. 456 // Arguments adaptor can not be topmost or bottommost.
458 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 457 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
459 ASSERT(output_[frame_index] == NULL); 458 ASSERT(output_[frame_index] == NULL);
460 output_[frame_index] = output_frame; 459 output_[frame_index] = output_frame;
461 460
462 // The top address of the frame is computed from the previous 461 // The top address of the frame is computed from the previous
463 // frame's top and this frame's size. 462 // frame's top and this frame's size.
464 uint32_t top_address; 463 uint32_t top_address;
465 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 464 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
466 output_frame->SetTop(top_address); 465 output_frame->SetTop(top_address);
467 466
468 // Compute the incoming parameter translation. 467 // Compute the incoming parameter translation.
469 int parameter_count = height; 468 int parameter_count = height;
470 unsigned output_offset = output_frame_size; 469 unsigned output_offset = output_frame_size;
471 unsigned input_offset = input_frame_size;
472 for (int i = 0; i < parameter_count; ++i) { 470 for (int i = 0; i < parameter_count; ++i) {
473 output_offset -= kPointerSize; 471 output_offset -= kPointerSize;
474 DoTranslateCommand(iterator, frame_index, output_offset); 472 DoTranslateCommand(iterator, frame_index, output_offset);
475 } 473 }
476 input_offset -= (parameter_count * kPointerSize);
477 474
478 // Read caller's PC from the previous frame. 475 // Read caller's PC from the previous frame.
479 output_offset -= kPointerSize; 476 output_offset -= kPointerSize;
480 input_offset -= kPointerSize;
481 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 477 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
482 output_frame->SetFrameSlot(output_offset, callers_pc); 478 output_frame->SetFrameSlot(output_offset, callers_pc);
483 if (FLAG_trace_deopt) { 479 if (FLAG_trace_deopt) {
484 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", 480 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
485 top_address + output_offset, output_offset, callers_pc); 481 top_address + output_offset, output_offset, callers_pc);
486 } 482 }
487 483
488 // Read caller's FP from the previous frame, and set this frame's FP. 484 // Read caller's FP from the previous frame, and set this frame's FP.
489 output_offset -= kPointerSize; 485 output_offset -= kPointerSize;
490 input_offset -= kPointerSize;
491 intptr_t value = output_[frame_index - 1]->GetFp(); 486 intptr_t value = output_[frame_index - 1]->GetFp();
492 output_frame->SetFrameSlot(output_offset, value); 487 output_frame->SetFrameSlot(output_offset, value);
493 intptr_t fp_value = top_address + output_offset; 488 intptr_t fp_value = top_address + output_offset;
494 output_frame->SetFp(fp_value); 489 output_frame->SetFp(fp_value);
495 if (FLAG_trace_deopt) { 490 if (FLAG_trace_deopt) {
496 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 491 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
497 fp_value, output_offset, value); 492 fp_value, output_offset, value);
498 } 493 }
499 494
500 // A marker value is used in place of the context. 495 // A marker value is used in place of the context.
501 output_offset -= kPointerSize; 496 output_offset -= kPointerSize;
502 input_offset -= kPointerSize;
503 intptr_t context = reinterpret_cast<intptr_t>( 497 intptr_t context = reinterpret_cast<intptr_t>(
504 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 498 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
505 output_frame->SetFrameSlot(output_offset, context); 499 output_frame->SetFrameSlot(output_offset, context);
506 if (FLAG_trace_deopt) { 500 if (FLAG_trace_deopt) {
507 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", 501 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n",
508 top_address + output_offset, output_offset, context); 502 top_address + output_offset, output_offset, context);
509 } 503 }
510 504
511 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. 505 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
512 output_offset -= kPointerSize; 506 output_offset -= kPointerSize;
513 input_offset -= kPointerSize;
514 value = reinterpret_cast<intptr_t>(function); 507 value = reinterpret_cast<intptr_t>(function);
515 output_frame->SetFrameSlot(output_offset, value); 508 output_frame->SetFrameSlot(output_offset, value);
516 if (FLAG_trace_deopt) { 509 if (FLAG_trace_deopt) {
517 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", 510 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n",
518 top_address + output_offset, output_offset, value); 511 top_address + output_offset, output_offset, value);
519 } 512 }
520 513
521 // Number of incoming arguments. 514 // Number of incoming arguments.
522 output_offset -= kPointerSize; 515 output_offset -= kPointerSize;
523 input_offset -= kPointerSize;
524 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); 516 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
525 output_frame->SetFrameSlot(output_offset, value); 517 output_frame->SetFrameSlot(output_offset, value);
526 if (FLAG_trace_deopt) { 518 if (FLAG_trace_deopt) {
527 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", 519 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
528 top_address + output_offset, output_offset, value, height - 1); 520 top_address + output_offset, output_offset, value, height - 1);
529 } 521 }
530 522
531 ASSERT(0 == output_offset); 523 ASSERT(0 == output_offset);
532 524
533 Builtins* builtins = isolate_->builtins(); 525 Builtins* builtins = isolate_->builtins();
534 Code* adaptor_trampoline = 526 Code* adaptor_trampoline =
535 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 527 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
536 uint32_t pc = reinterpret_cast<uint32_t>( 528 uint32_t pc = reinterpret_cast<uint32_t>(
537 adaptor_trampoline->instruction_start() + 529 adaptor_trampoline->instruction_start() +
538 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 530 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
539 output_frame->SetPc(pc); 531 output_frame->SetPc(pc);
540 } 532 }
541 533
542 534
535 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
536 int frame_index) {
537 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
538 unsigned height = iterator->Next();
539 unsigned height_in_bytes = height * kPointerSize;
540 if (FLAG_trace_deopt) {
541 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
542 }
543
544 unsigned fixed_frame_size = 6 * kPointerSize;
545 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
546
547 // Allocate and store the output frame description.
548 FrameDescription* output_frame =
549 new(output_frame_size) FrameDescription(output_frame_size, function);
550 output_frame->SetFrameType(StackFrame::CONSTRUCT);
551
552 // Construct stub can not be topmost or bottommost.
553 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
554 ASSERT(output_[frame_index] == NULL);
555 output_[frame_index] = output_frame;
556
557 // The top address of the frame is computed from the previous
558 // frame's top and this frame's size.
559 uint32_t top_address;
560 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
561 output_frame->SetTop(top_address);
562
563 // Compute the incoming parameter translation.
564 int parameter_count = height;
565 unsigned output_offset = output_frame_size;
566 for (int i = 0; i < parameter_count; ++i) {
567 output_offset -= kPointerSize;
568 DoTranslateCommand(iterator, frame_index, output_offset);
569 }
570
571 // Read caller's PC from the previous frame.
572 output_offset -= kPointerSize;
573 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
574 output_frame->SetFrameSlot(output_offset, callers_pc);
575 if (FLAG_trace_deopt) {
576 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
577 top_address + output_offset, output_offset, callers_pc);
578 }
579
580 // Read caller's FP from the previous frame, and set this frame's FP.
581 output_offset -= kPointerSize;
582 intptr_t value = output_[frame_index - 1]->GetFp();
583 output_frame->SetFrameSlot(output_offset, value);
584 intptr_t fp_value = top_address + output_offset;
585 output_frame->SetFp(fp_value);
586 if (FLAG_trace_deopt) {
587 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
588 fp_value, output_offset, value);
589 }
590
591 // The context can be gotten from the previous frame.
592 output_offset -= kPointerSize;
593 value = output_[frame_index - 1]->GetContext();
594 output_frame->SetFrameSlot(output_offset, value);
595 if (FLAG_trace_deopt) {
596 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
597 top_address + output_offset, output_offset, value);
598 }
599
600 // A marker value is used in place of the function.
601 output_offset -= kPointerSize;
602 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
603 output_frame->SetFrameSlot(output_offset, value);
604 if (FLAG_trace_deopt) {
605 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n",
606 top_address + output_offset, output_offset, value);
607 }
608
609 // Number of incoming arguments.
610 output_offset -= kPointerSize;
611 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
612 output_frame->SetFrameSlot(output_offset, value);
613 if (FLAG_trace_deopt) {
614 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
615 top_address + output_offset, output_offset, value, height - 1);
616 }
617
618 // The newly allocated object was passed as receiver in the artificial
619 // constructor stub environment created by HEnvironment::CopyForInlining().
620 output_offset -= kPointerSize;
621 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
622 output_frame->SetFrameSlot(output_offset, value);
623 if (FLAG_trace_deopt) {
624 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n",
625 top_address + output_offset, output_offset, value);
626 }
627
628 ASSERT(0 == output_offset);
629
630 Builtins* builtins = isolate_->builtins();
631 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
632 uint32_t pc = reinterpret_cast<uint32_t>(
633 construct_stub->instruction_start() +
634 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
635 output_frame->SetPc(pc);
636 }
637
638
543 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 639 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
544 int frame_index) { 640 int frame_index) {
545 int node_id = iterator->Next(); 641 int node_id = iterator->Next();
546 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 642 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
547 unsigned height = iterator->Next(); 643 unsigned height = iterator->Next();
548 unsigned height_in_bytes = height * kPointerSize; 644 unsigned height_in_bytes = height * kPointerSize;
549 if (FLAG_trace_deopt) { 645 if (FLAG_trace_deopt) {
550 PrintF(" translating "); 646 PrintF(" translating ");
551 function->PrintName(); 647 function->PrintName();
552 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 648 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 // frame. For all subsequent output frames it can be gotten from the function 740 // frame. For all subsequent output frames it can be gotten from the function
645 // so long as we don't inline functions that need local contexts. 741 // so long as we don't inline functions that need local contexts.
646 output_offset -= kPointerSize; 742 output_offset -= kPointerSize;
647 input_offset -= kPointerSize; 743 input_offset -= kPointerSize;
648 if (is_bottommost) { 744 if (is_bottommost) {
649 value = input_->GetFrameSlot(input_offset); 745 value = input_->GetFrameSlot(input_offset);
650 } else { 746 } else {
651 value = reinterpret_cast<uint32_t>(function->context()); 747 value = reinterpret_cast<uint32_t>(function->context());
652 } 748 }
653 output_frame->SetFrameSlot(output_offset, value); 749 output_frame->SetFrameSlot(output_offset, value);
750 output_frame->SetContext(value);
654 if (is_topmost) output_frame->SetRegister(esi.code(), value); 751 if (is_topmost) output_frame->SetRegister(esi.code(), value);
655 if (FLAG_trace_deopt) { 752 if (FLAG_trace_deopt) {
656 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", 753 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
657 top_address + output_offset, output_offset, value); 754 top_address + output_offset, output_offset, value);
658 } 755 }
659 756
660 // The function was mentioned explicitly in the BEGIN_FRAME. 757 // The function was mentioned explicitly in the BEGIN_FRAME.
661 output_offset -= kPointerSize; 758 output_offset -= kPointerSize;
662 input_offset -= kPointerSize; 759 input_offset -= kPointerSize;
663 value = reinterpret_cast<uint32_t>(function); 760 value = reinterpret_cast<uint32_t>(function);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 } 1014 }
918 __ bind(&done); 1015 __ bind(&done);
919 } 1016 }
920 1017
921 #undef __ 1018 #undef __
922 1019
923 1020
924 } } // namespace v8::internal 1021 } } // namespace v8::internal
925 1022
926 #endif // V8_TARGET_ARCH_IA32 1023 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698