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

Side by Side Diff: src/arm/deoptimizer-arm.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/arm/builtins-arm.cc ('k') | src/arm/full-codegen-arm.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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 344 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
345 int frame_index) { 345 int frame_index) {
346 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 346 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
347 unsigned height = iterator->Next(); 347 unsigned height = iterator->Next();
348 unsigned height_in_bytes = height * kPointerSize; 348 unsigned height_in_bytes = height * kPointerSize;
349 if (FLAG_trace_deopt) { 349 if (FLAG_trace_deopt) {
350 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); 350 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
351 } 351 }
352 352
353 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 353 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
354 unsigned input_frame_size = input_->GetFrameSize();
355 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 354 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
356 355
357 // Allocate and store the output frame description. 356 // Allocate and store the output frame description.
358 FrameDescription* output_frame = 357 FrameDescription* output_frame =
359 new(output_frame_size) FrameDescription(output_frame_size, function); 358 new(output_frame_size) FrameDescription(output_frame_size, function);
360 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 359 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
361 360
362 // Arguments adaptor can not be topmost or bottommost. 361 // Arguments adaptor can not be topmost or bottommost.
363 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 362 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
364 ASSERT(output_[frame_index] == NULL); 363 ASSERT(output_[frame_index] == NULL);
365 output_[frame_index] = output_frame; 364 output_[frame_index] = output_frame;
366 365
367 // The top address of the frame is computed from the previous 366 // The top address of the frame is computed from the previous
368 // frame's top and this frame's size. 367 // frame's top and this frame's size.
369 uint32_t top_address; 368 uint32_t top_address;
370 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 369 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
371 output_frame->SetTop(top_address); 370 output_frame->SetTop(top_address);
372 371
373 // Compute the incoming parameter translation. 372 // Compute the incoming parameter translation.
374 int parameter_count = height; 373 int parameter_count = height;
375 unsigned output_offset = output_frame_size; 374 unsigned output_offset = output_frame_size;
376 unsigned input_offset = input_frame_size;
377 for (int i = 0; i < parameter_count; ++i) { 375 for (int i = 0; i < parameter_count; ++i) {
378 output_offset -= kPointerSize; 376 output_offset -= kPointerSize;
379 DoTranslateCommand(iterator, frame_index, output_offset); 377 DoTranslateCommand(iterator, frame_index, output_offset);
380 } 378 }
381 input_offset -= (parameter_count * kPointerSize);
382 379
383 // Read caller's PC from the previous frame. 380 // Read caller's PC from the previous frame.
384 output_offset -= kPointerSize; 381 output_offset -= kPointerSize;
385 input_offset -= kPointerSize;
386 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 382 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
387 output_frame->SetFrameSlot(output_offset, callers_pc); 383 output_frame->SetFrameSlot(output_offset, callers_pc);
388 if (FLAG_trace_deopt) { 384 if (FLAG_trace_deopt) {
389 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", 385 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
390 top_address + output_offset, output_offset, callers_pc); 386 top_address + output_offset, output_offset, callers_pc);
391 } 387 }
392 388
393 // Read caller's FP from the previous frame, and set this frame's FP. 389 // Read caller's FP from the previous frame, and set this frame's FP.
394 output_offset -= kPointerSize; 390 output_offset -= kPointerSize;
395 input_offset -= kPointerSize;
396 intptr_t value = output_[frame_index - 1]->GetFp(); 391 intptr_t value = output_[frame_index - 1]->GetFp();
397 output_frame->SetFrameSlot(output_offset, value); 392 output_frame->SetFrameSlot(output_offset, value);
398 intptr_t fp_value = top_address + output_offset; 393 intptr_t fp_value = top_address + output_offset;
399 output_frame->SetFp(fp_value); 394 output_frame->SetFp(fp_value);
400 if (FLAG_trace_deopt) { 395 if (FLAG_trace_deopt) {
401 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 396 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
402 fp_value, output_offset, value); 397 fp_value, output_offset, value);
403 } 398 }
404 399
405 // A marker value is used in place of the context. 400 // A marker value is used in place of the context.
406 output_offset -= kPointerSize; 401 output_offset -= kPointerSize;
407 input_offset -= kPointerSize;
408 intptr_t context = reinterpret_cast<intptr_t>( 402 intptr_t context = reinterpret_cast<intptr_t>(
409 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 403 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
410 output_frame->SetFrameSlot(output_offset, context); 404 output_frame->SetFrameSlot(output_offset, context);
411 if (FLAG_trace_deopt) { 405 if (FLAG_trace_deopt) {
412 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", 406 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n",
413 top_address + output_offset, output_offset, context); 407 top_address + output_offset, output_offset, context);
414 } 408 }
415 409
416 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. 410 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
417 output_offset -= kPointerSize; 411 output_offset -= kPointerSize;
418 input_offset -= kPointerSize;
419 value = reinterpret_cast<intptr_t>(function); 412 value = reinterpret_cast<intptr_t>(function);
420 output_frame->SetFrameSlot(output_offset, value); 413 output_frame->SetFrameSlot(output_offset, value);
421 if (FLAG_trace_deopt) { 414 if (FLAG_trace_deopt) {
422 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", 415 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n",
423 top_address + output_offset, output_offset, value); 416 top_address + output_offset, output_offset, value);
424 } 417 }
425 418
426 // Number of incoming arguments. 419 // Number of incoming arguments.
427 output_offset -= kPointerSize; 420 output_offset -= kPointerSize;
428 input_offset -= kPointerSize;
429 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); 421 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
430 output_frame->SetFrameSlot(output_offset, value); 422 output_frame->SetFrameSlot(output_offset, value);
431 if (FLAG_trace_deopt) { 423 if (FLAG_trace_deopt) {
432 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", 424 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
433 top_address + output_offset, output_offset, value, height - 1); 425 top_address + output_offset, output_offset, value, height - 1);
434 } 426 }
435 427
436 ASSERT(0 == output_offset); 428 ASSERT(0 == output_offset);
437 429
438 Builtins* builtins = isolate_->builtins(); 430 Builtins* builtins = isolate_->builtins();
439 Code* adaptor_trampoline = 431 Code* adaptor_trampoline =
440 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 432 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
441 uint32_t pc = reinterpret_cast<uint32_t>( 433 uint32_t pc = reinterpret_cast<uint32_t>(
442 adaptor_trampoline->instruction_start() + 434 adaptor_trampoline->instruction_start() +
443 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 435 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
444 output_frame->SetPc(pc); 436 output_frame->SetPc(pc);
445 } 437 }
446 438
447 439
440 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
441 int frame_index) {
442 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
443 unsigned height = iterator->Next();
444 unsigned height_in_bytes = height * kPointerSize;
445 if (FLAG_trace_deopt) {
446 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
447 }
448
449 unsigned fixed_frame_size = 7 * kPointerSize;
450 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
451
452 // Allocate and store the output frame description.
453 FrameDescription* output_frame =
454 new(output_frame_size) FrameDescription(output_frame_size, function);
455 output_frame->SetFrameType(StackFrame::CONSTRUCT);
456
457 // Construct stub can not be topmost or bottommost.
458 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
459 ASSERT(output_[frame_index] == NULL);
460 output_[frame_index] = output_frame;
461
462 // The top address of the frame is computed from the previous
463 // frame's top and this frame's size.
464 uint32_t top_address;
465 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
466 output_frame->SetTop(top_address);
467
468 // Compute the incoming parameter translation.
469 int parameter_count = height;
470 unsigned output_offset = output_frame_size;
471 for (int i = 0; i < parameter_count; ++i) {
472 output_offset -= kPointerSize;
473 DoTranslateCommand(iterator, frame_index, output_offset);
474 }
475
476 // Read caller's PC from the previous frame.
477 output_offset -= kPointerSize;
478 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
479 output_frame->SetFrameSlot(output_offset, callers_pc);
480 if (FLAG_trace_deopt) {
481 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
482 top_address + output_offset, output_offset, callers_pc);
483 }
484
485 // Read caller's FP from the previous frame, and set this frame's FP.
486 output_offset -= kPointerSize;
487 intptr_t value = output_[frame_index - 1]->GetFp();
488 output_frame->SetFrameSlot(output_offset, value);
489 intptr_t fp_value = top_address + output_offset;
490 output_frame->SetFp(fp_value);
491 if (FLAG_trace_deopt) {
492 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
493 fp_value, output_offset, value);
494 }
495
496 // The context can be gotten from the previous frame.
497 output_offset -= kPointerSize;
498 value = output_[frame_index - 1]->GetContext();
499 output_frame->SetFrameSlot(output_offset, value);
500 if (FLAG_trace_deopt) {
501 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
502 top_address + output_offset, output_offset, value);
503 }
504
505 // A marker value is used in place of the function.
506 output_offset -= kPointerSize;
507 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
508 output_frame->SetFrameSlot(output_offset, value);
509 if (FLAG_trace_deopt) {
510 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n",
511 top_address + output_offset, output_offset, value);
512 }
513
514 // Number of incoming arguments.
515 output_offset -= kPointerSize;
516 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
517 output_frame->SetFrameSlot(output_offset, value);
518 if (FLAG_trace_deopt) {
519 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
520 top_address + output_offset, output_offset, value, height - 1);
521 }
522
523 // Constructor function being invoked by the stub.
524 output_offset -= kPointerSize;
525 value = reinterpret_cast<intptr_t>(function);
526 output_frame->SetFrameSlot(output_offset, value);
527 if (FLAG_trace_deopt) {
528 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n",
529 top_address + output_offset, output_offset, value);
530 }
531
532 // The newly allocated object was passed as receiver in the artificial
533 // constructor stub environment created by HEnvironment::CopyForInlining().
534 output_offset -= kPointerSize;
535 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
536 output_frame->SetFrameSlot(output_offset, value);
537 if (FLAG_trace_deopt) {
538 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n",
539 top_address + output_offset, output_offset, value);
540 }
541
542 ASSERT(0 == output_offset);
543
544 Builtins* builtins = isolate_->builtins();
545 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
546 uint32_t pc = reinterpret_cast<uint32_t>(
547 construct_stub->instruction_start() +
548 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
549 output_frame->SetPc(pc);
550 }
551
552
448 // This code is very similar to ia32 code, but relies on register names (fp, sp) 553 // This code is very similar to ia32 code, but relies on register names (fp, sp)
449 // and how the frame is laid out. 554 // and how the frame is laid out.
450 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 555 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
451 int frame_index) { 556 int frame_index) {
452 // Read the ast node id, function, and frame height for this output frame. 557 // Read the ast node id, function, and frame height for this output frame.
453 int node_id = iterator->Next(); 558 int node_id = iterator->Next();
454 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 559 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
455 unsigned height = iterator->Next(); 560 unsigned height = iterator->Next();
456 unsigned height_in_bytes = height * kPointerSize; 561 unsigned height_in_bytes = height * kPointerSize;
457 if (FLAG_trace_deopt) { 562 if (FLAG_trace_deopt) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 // frame. For all subsequent output frames it can be gotten from the function 655 // frame. For all subsequent output frames it can be gotten from the function
551 // so long as we don't inline functions that need local contexts. 656 // so long as we don't inline functions that need local contexts.
552 output_offset -= kPointerSize; 657 output_offset -= kPointerSize;
553 input_offset -= kPointerSize; 658 input_offset -= kPointerSize;
554 if (is_bottommost) { 659 if (is_bottommost) {
555 value = input_->GetFrameSlot(input_offset); 660 value = input_->GetFrameSlot(input_offset);
556 } else { 661 } else {
557 value = reinterpret_cast<intptr_t>(function->context()); 662 value = reinterpret_cast<intptr_t>(function->context());
558 } 663 }
559 output_frame->SetFrameSlot(output_offset, value); 664 output_frame->SetFrameSlot(output_offset, value);
560 if (is_topmost) { 665 output_frame->SetContext(value);
561 output_frame->SetRegister(cp.code(), value); 666 if (is_topmost) output_frame->SetRegister(cp.code(), value);
562 }
563 if (FLAG_trace_deopt) { 667 if (FLAG_trace_deopt) {
564 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", 668 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
565 top_address + output_offset, output_offset, value); 669 top_address + output_offset, output_offset, value);
566 } 670 }
567 671
568 // The function was mentioned explicitly in the BEGIN_FRAME. 672 // The function was mentioned explicitly in the BEGIN_FRAME.
569 output_offset -= kPointerSize; 673 output_offset -= kPointerSize;
570 input_offset -= kPointerSize; 674 input_offset -= kPointerSize;
571 value = reinterpret_cast<uint32_t>(function); 675 value = reinterpret_cast<uint32_t>(function);
572 // The function for the bottommost output frame should also agree with the 676 // The function for the bottommost output frame should also agree with the
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 __ push(ip); 951 __ push(ip);
848 __ b(&done); 952 __ b(&done);
849 ASSERT(masm()->pc_offset() - start == table_entry_size_); 953 ASSERT(masm()->pc_offset() - start == table_entry_size_);
850 } 954 }
851 __ bind(&done); 955 __ bind(&done);
852 } 956 }
853 957
854 #undef __ 958 #undef __
855 959
856 } } // namespace v8::internal 960 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698