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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 mov(object, Immediate(BitCast<int32_t>(kZapValue))); | 145 mov(object, Immediate(BitCast<int32_t>(kZapValue))); |
146 mov(address, Immediate(BitCast<int32_t>(kZapValue))); | 146 mov(address, Immediate(BitCast<int32_t>(kZapValue))); |
147 mov(value, Immediate(BitCast<int32_t>(kZapValue))); | 147 mov(value, Immediate(BitCast<int32_t>(kZapValue))); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 #ifdef ENABLE_DEBUGGER_SUPPORT | 152 #ifdef ENABLE_DEBUGGER_SUPPORT |
153 void MacroAssembler::DebugBreak() { | 153 void MacroAssembler::DebugBreak() { |
154 Set(eax, Immediate(0)); | 154 Set(eax, Immediate(0)); |
155 mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak))); | 155 mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak, isolate()))); |
156 CEntryStub ces(1); | 156 CEntryStub ces(1); |
157 call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 157 call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
158 } | 158 } |
159 #endif | 159 #endif |
160 | 160 |
161 | 161 |
162 void MacroAssembler::Set(Register dst, const Immediate& x) { | 162 void MacroAssembler::Set(Register dst, const Immediate& x) { |
163 if (x.is_zero()) { | 163 if (x.is_zero()) { |
164 xor_(dst, Operand(dst)); // shorter than mov | 164 xor_(dst, Operand(dst)); // shorter than mov |
165 } else { | 165 } else { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | 309 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); |
310 push(ebp); | 310 push(ebp); |
311 mov(ebp, Operand(esp)); | 311 mov(ebp, Operand(esp)); |
312 | 312 |
313 // Reserve room for entry stack pointer and push the code object. | 313 // Reserve room for entry stack pointer and push the code object. |
314 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 314 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
315 push(Immediate(0)); // Saved entry sp, patched before call. | 315 push(Immediate(0)); // Saved entry sp, patched before call. |
316 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 316 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
317 | 317 |
318 // Save the frame pointer and the context in top. | 318 // Save the frame pointer and the context in top. |
319 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); | 319 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, |
320 ExternalReference context_address(Isolate::k_context_address); | 320 isolate()); |
| 321 ExternalReference context_address(Isolate::k_context_address, |
| 322 isolate()); |
321 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 323 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
322 mov(Operand::StaticVariable(context_address), esi); | 324 mov(Operand::StaticVariable(context_address), esi); |
323 } | 325 } |
324 | 326 |
325 | 327 |
326 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { | 328 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { |
327 // Optionally save all XMM registers. | 329 // Optionally save all XMM registers. |
328 if (save_doubles) { | 330 if (save_doubles) { |
329 CpuFeatures::Scope scope(SSE2); | 331 CpuFeatures::Scope scope(SSE2); |
330 int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize; | 332 int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 lea(esp, Operand(esi, 1 * kPointerSize)); | 390 lea(esp, Operand(esi, 1 * kPointerSize)); |
389 | 391 |
390 // Push the return address to get ready to return. | 392 // Push the return address to get ready to return. |
391 push(ecx); | 393 push(ecx); |
392 | 394 |
393 LeaveExitFrameEpilogue(); | 395 LeaveExitFrameEpilogue(); |
394 } | 396 } |
395 | 397 |
396 void MacroAssembler::LeaveExitFrameEpilogue() { | 398 void MacroAssembler::LeaveExitFrameEpilogue() { |
397 // Restore current context from top and clear it in debug mode. | 399 // Restore current context from top and clear it in debug mode. |
398 ExternalReference context_address(Isolate::k_context_address); | 400 ExternalReference context_address(Isolate::k_context_address, isolate()); |
399 mov(esi, Operand::StaticVariable(context_address)); | 401 mov(esi, Operand::StaticVariable(context_address)); |
400 #ifdef DEBUG | 402 #ifdef DEBUG |
401 mov(Operand::StaticVariable(context_address), Immediate(0)); | 403 mov(Operand::StaticVariable(context_address), Immediate(0)); |
402 #endif | 404 #endif |
403 | 405 |
404 // Clear the top frame. | 406 // Clear the top frame. |
405 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); | 407 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, |
| 408 isolate()); |
406 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | 409 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); |
407 } | 410 } |
408 | 411 |
409 | 412 |
410 void MacroAssembler::LeaveApiExitFrame() { | 413 void MacroAssembler::LeaveApiExitFrame() { |
411 mov(esp, Operand(ebp)); | 414 mov(esp, Operand(ebp)); |
412 pop(ebp); | 415 pop(ebp); |
413 | 416 |
414 LeaveExitFrameEpilogue(); | 417 LeaveExitFrameEpilogue(); |
415 } | 418 } |
(...skipping 13 matching lines...) Expand all Loading... |
429 push(ebp); | 432 push(ebp); |
430 } else { | 433 } else { |
431 ASSERT(try_location == IN_JS_ENTRY); | 434 ASSERT(try_location == IN_JS_ENTRY); |
432 // The frame pointer does not point to a JS frame so we save NULL | 435 // The frame pointer does not point to a JS frame so we save NULL |
433 // for ebp. We expect the code throwing an exception to check ebp | 436 // for ebp. We expect the code throwing an exception to check ebp |
434 // before dereferencing it to restore the context. | 437 // before dereferencing it to restore the context. |
435 push(Immediate(StackHandler::ENTRY)); | 438 push(Immediate(StackHandler::ENTRY)); |
436 push(Immediate(0)); // NULL frame pointer. | 439 push(Immediate(0)); // NULL frame pointer. |
437 } | 440 } |
438 // Save the current handler as the next handler. | 441 // Save the current handler as the next handler. |
439 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address))); | 442 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 443 isolate()))); |
440 // Link this handler as the new current one. | 444 // Link this handler as the new current one. |
441 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address)), | 445 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 446 isolate())), |
442 esp); | 447 esp); |
443 } | 448 } |
444 | 449 |
445 | 450 |
446 void MacroAssembler::PopTryHandler() { | 451 void MacroAssembler::PopTryHandler() { |
447 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 452 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
448 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address))); | 453 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 454 isolate()))); |
449 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 455 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |
450 } | 456 } |
451 | 457 |
452 | 458 |
453 void MacroAssembler::Throw(Register value) { | 459 void MacroAssembler::Throw(Register value) { |
454 // Adjust this code if not the case. | 460 // Adjust this code if not the case. |
455 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 461 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
456 | 462 |
457 // eax must hold the exception. | 463 // eax must hold the exception. |
458 if (!value.is(eax)) { | 464 if (!value.is(eax)) { |
459 mov(eax, value); | 465 mov(eax, value); |
460 } | 466 } |
461 | 467 |
462 // Drop the sp to the top of the handler. | 468 // Drop the sp to the top of the handler. |
463 ExternalReference handler_address(Isolate::k_handler_address); | 469 ExternalReference handler_address(Isolate::k_handler_address, |
| 470 isolate()); |
464 mov(esp, Operand::StaticVariable(handler_address)); | 471 mov(esp, Operand::StaticVariable(handler_address)); |
465 | 472 |
466 // Restore next handler and frame pointer, discard handler state. | 473 // Restore next handler and frame pointer, discard handler state. |
467 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 474 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
468 pop(Operand::StaticVariable(handler_address)); | 475 pop(Operand::StaticVariable(handler_address)); |
469 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 476 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
470 pop(ebp); | 477 pop(ebp); |
471 pop(edx); // Remove state. | 478 pop(edx); // Remove state. |
472 | 479 |
473 // Before returning we restore the context from the frame pointer if | 480 // Before returning we restore the context from the frame pointer if |
(...skipping 15 matching lines...) Expand all Loading... |
489 Register value) { | 496 Register value) { |
490 // Adjust this code if not the case. | 497 // Adjust this code if not the case. |
491 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 498 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
492 | 499 |
493 // eax must hold the exception. | 500 // eax must hold the exception. |
494 if (!value.is(eax)) { | 501 if (!value.is(eax)) { |
495 mov(eax, value); | 502 mov(eax, value); |
496 } | 503 } |
497 | 504 |
498 // Drop sp to the top stack handler. | 505 // Drop sp to the top stack handler. |
499 ExternalReference handler_address(Isolate::k_handler_address); | 506 ExternalReference handler_address(Isolate::k_handler_address, |
| 507 isolate()); |
500 mov(esp, Operand::StaticVariable(handler_address)); | 508 mov(esp, Operand::StaticVariable(handler_address)); |
501 | 509 |
502 // Unwind the handlers until the ENTRY handler is found. | 510 // Unwind the handlers until the ENTRY handler is found. |
503 NearLabel loop, done; | 511 NearLabel loop, done; |
504 bind(&loop); | 512 bind(&loop); |
505 // Load the type of the current stack handler. | 513 // Load the type of the current stack handler. |
506 const int kStateOffset = StackHandlerConstants::kStateOffset; | 514 const int kStateOffset = StackHandlerConstants::kStateOffset; |
507 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | 515 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
508 j(equal, &done); | 516 j(equal, &done); |
509 // Fetch the next handler in the list. | 517 // Fetch the next handler in the list. |
510 const int kNextOffset = StackHandlerConstants::kNextOffset; | 518 const int kNextOffset = StackHandlerConstants::kNextOffset; |
511 mov(esp, Operand(esp, kNextOffset)); | 519 mov(esp, Operand(esp, kNextOffset)); |
512 jmp(&loop); | 520 jmp(&loop); |
513 bind(&done); | 521 bind(&done); |
514 | 522 |
515 // Set the top handler address to next handler past the current ENTRY handler. | 523 // Set the top handler address to next handler past the current ENTRY handler. |
516 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 524 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
517 pop(Operand::StaticVariable(handler_address)); | 525 pop(Operand::StaticVariable(handler_address)); |
518 | 526 |
519 if (type == OUT_OF_MEMORY) { | 527 if (type == OUT_OF_MEMORY) { |
520 // Set external caught exception to false. | 528 // Set external caught exception to false. |
521 ExternalReference external_caught( | 529 ExternalReference external_caught( |
522 Isolate::k_external_caught_exception_address); | 530 Isolate::k_external_caught_exception_address, |
| 531 isolate()); |
523 mov(eax, false); | 532 mov(eax, false); |
524 mov(Operand::StaticVariable(external_caught), eax); | 533 mov(Operand::StaticVariable(external_caught), eax); |
525 | 534 |
526 // Set pending exception and eax to out of memory exception. | 535 // Set pending exception and eax to out of memory exception. |
527 ExternalReference pending_exception(Isolate::k_pending_exception_address); | 536 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 537 isolate()); |
528 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 538 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
529 mov(Operand::StaticVariable(pending_exception), eax); | 539 mov(Operand::StaticVariable(pending_exception), eax); |
530 } | 540 } |
531 | 541 |
532 // Clear the context pointer. | 542 // Clear the context pointer. |
533 Set(esi, Immediate(0)); | 543 Set(esi, Immediate(0)); |
534 | 544 |
535 // Restore fp from handler and discard handler state. | 545 // Restore fp from handler and discard handler state. |
536 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 546 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
537 pop(ebp); | 547 pop(ebp); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 j(not_equal, miss, not_taken); | 617 j(not_equal, miss, not_taken); |
608 | 618 |
609 bind(&same_contexts); | 619 bind(&same_contexts); |
610 } | 620 } |
611 | 621 |
612 | 622 |
613 void MacroAssembler::LoadAllocationTopHelper(Register result, | 623 void MacroAssembler::LoadAllocationTopHelper(Register result, |
614 Register scratch, | 624 Register scratch, |
615 AllocationFlags flags) { | 625 AllocationFlags flags) { |
616 ExternalReference new_space_allocation_top = | 626 ExternalReference new_space_allocation_top = |
617 ExternalReference::new_space_allocation_top_address(); | 627 ExternalReference::new_space_allocation_top_address(isolate()); |
618 | 628 |
619 // Just return if allocation top is already known. | 629 // Just return if allocation top is already known. |
620 if ((flags & RESULT_CONTAINS_TOP) != 0) { | 630 if ((flags & RESULT_CONTAINS_TOP) != 0) { |
621 // No use of scratch if allocation top is provided. | 631 // No use of scratch if allocation top is provided. |
622 ASSERT(scratch.is(no_reg)); | 632 ASSERT(scratch.is(no_reg)); |
623 #ifdef DEBUG | 633 #ifdef DEBUG |
624 // Assert that result actually contains top on entry. | 634 // Assert that result actually contains top on entry. |
625 cmp(result, Operand::StaticVariable(new_space_allocation_top)); | 635 cmp(result, Operand::StaticVariable(new_space_allocation_top)); |
626 Check(equal, "Unexpected allocation top"); | 636 Check(equal, "Unexpected allocation top"); |
627 #endif | 637 #endif |
(...skipping 11 matching lines...) Expand all Loading... |
639 | 649 |
640 | 650 |
641 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, | 651 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, |
642 Register scratch) { | 652 Register scratch) { |
643 if (emit_debug_code()) { | 653 if (emit_debug_code()) { |
644 test(result_end, Immediate(kObjectAlignmentMask)); | 654 test(result_end, Immediate(kObjectAlignmentMask)); |
645 Check(zero, "Unaligned allocation in new space"); | 655 Check(zero, "Unaligned allocation in new space"); |
646 } | 656 } |
647 | 657 |
648 ExternalReference new_space_allocation_top = | 658 ExternalReference new_space_allocation_top = |
649 ExternalReference::new_space_allocation_top_address(); | 659 ExternalReference::new_space_allocation_top_address(isolate()); |
650 | 660 |
651 // Update new top. Use scratch if available. | 661 // Update new top. Use scratch if available. |
652 if (scratch.is(no_reg)) { | 662 if (scratch.is(no_reg)) { |
653 mov(Operand::StaticVariable(new_space_allocation_top), result_end); | 663 mov(Operand::StaticVariable(new_space_allocation_top), result_end); |
654 } else { | 664 } else { |
655 mov(Operand(scratch, 0), result_end); | 665 mov(Operand(scratch, 0), result_end); |
656 } | 666 } |
657 } | 667 } |
658 | 668 |
659 | 669 |
(...skipping 19 matching lines...) Expand all Loading... |
679 } | 689 } |
680 ASSERT(!result.is(result_end)); | 690 ASSERT(!result.is(result_end)); |
681 | 691 |
682 // Load address of new object into result. | 692 // Load address of new object into result. |
683 LoadAllocationTopHelper(result, scratch, flags); | 693 LoadAllocationTopHelper(result, scratch, flags); |
684 | 694 |
685 Register top_reg = result_end.is_valid() ? result_end : result; | 695 Register top_reg = result_end.is_valid() ? result_end : result; |
686 | 696 |
687 // Calculate new top and bail out if new space is exhausted. | 697 // Calculate new top and bail out if new space is exhausted. |
688 ExternalReference new_space_allocation_limit = | 698 ExternalReference new_space_allocation_limit = |
689 ExternalReference::new_space_allocation_limit_address(); | 699 ExternalReference::new_space_allocation_limit_address(isolate()); |
690 | 700 |
691 if (!top_reg.is(result)) { | 701 if (!top_reg.is(result)) { |
692 mov(top_reg, result); | 702 mov(top_reg, result); |
693 } | 703 } |
694 add(Operand(top_reg), Immediate(object_size)); | 704 add(Operand(top_reg), Immediate(object_size)); |
695 j(carry, gc_required, not_taken); | 705 j(carry, gc_required, not_taken); |
696 cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit)); | 706 cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit)); |
697 j(above, gc_required, not_taken); | 707 j(above, gc_required, not_taken); |
698 | 708 |
699 // Update allocation top. | 709 // Update allocation top. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 jmp(gc_required); | 743 jmp(gc_required); |
734 return; | 744 return; |
735 } | 745 } |
736 ASSERT(!result.is(result_end)); | 746 ASSERT(!result.is(result_end)); |
737 | 747 |
738 // Load address of new object into result. | 748 // Load address of new object into result. |
739 LoadAllocationTopHelper(result, scratch, flags); | 749 LoadAllocationTopHelper(result, scratch, flags); |
740 | 750 |
741 // Calculate new top and bail out if new space is exhausted. | 751 // Calculate new top and bail out if new space is exhausted. |
742 ExternalReference new_space_allocation_limit = | 752 ExternalReference new_space_allocation_limit = |
743 ExternalReference::new_space_allocation_limit_address(); | 753 ExternalReference::new_space_allocation_limit_address(isolate()); |
744 | 754 |
745 // We assume that element_count*element_size + header_size does not | 755 // We assume that element_count*element_size + header_size does not |
746 // overflow. | 756 // overflow. |
747 lea(result_end, Operand(element_count, element_size, header_size)); | 757 lea(result_end, Operand(element_count, element_size, header_size)); |
748 add(result_end, Operand(result)); | 758 add(result_end, Operand(result)); |
749 j(carry, gc_required); | 759 j(carry, gc_required); |
750 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit)); | 760 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit)); |
751 j(above, gc_required); | 761 j(above, gc_required); |
752 | 762 |
753 // Tag result if requested. | 763 // Tag result if requested. |
(...skipping 25 matching lines...) Expand all Loading... |
779 jmp(gc_required); | 789 jmp(gc_required); |
780 return; | 790 return; |
781 } | 791 } |
782 ASSERT(!result.is(result_end)); | 792 ASSERT(!result.is(result_end)); |
783 | 793 |
784 // Load address of new object into result. | 794 // Load address of new object into result. |
785 LoadAllocationTopHelper(result, scratch, flags); | 795 LoadAllocationTopHelper(result, scratch, flags); |
786 | 796 |
787 // Calculate new top and bail out if new space is exhausted. | 797 // Calculate new top and bail out if new space is exhausted. |
788 ExternalReference new_space_allocation_limit = | 798 ExternalReference new_space_allocation_limit = |
789 ExternalReference::new_space_allocation_limit_address(); | 799 ExternalReference::new_space_allocation_limit_address(isolate()); |
790 if (!object_size.is(result_end)) { | 800 if (!object_size.is(result_end)) { |
791 mov(result_end, object_size); | 801 mov(result_end, object_size); |
792 } | 802 } |
793 add(result_end, Operand(result)); | 803 add(result_end, Operand(result)); |
794 j(carry, gc_required, not_taken); | 804 j(carry, gc_required, not_taken); |
795 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit)); | 805 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit)); |
796 j(above, gc_required, not_taken); | 806 j(above, gc_required, not_taken); |
797 | 807 |
798 // Tag result if requested. | 808 // Tag result if requested. |
799 if ((flags & TAG_OBJECT) != 0) { | 809 if ((flags & TAG_OBJECT) != 0) { |
800 lea(result, Operand(result, kHeapObjectTag)); | 810 lea(result, Operand(result, kHeapObjectTag)); |
801 } | 811 } |
802 | 812 |
803 // Update allocation top. | 813 // Update allocation top. |
804 UpdateAllocationTopHelper(result_end, scratch); | 814 UpdateAllocationTopHelper(result_end, scratch); |
805 } | 815 } |
806 | 816 |
807 | 817 |
808 void MacroAssembler::UndoAllocationInNewSpace(Register object) { | 818 void MacroAssembler::UndoAllocationInNewSpace(Register object) { |
809 ExternalReference new_space_allocation_top = | 819 ExternalReference new_space_allocation_top = |
810 ExternalReference::new_space_allocation_top_address(); | 820 ExternalReference::new_space_allocation_top_address(isolate()); |
811 | 821 |
812 // Make sure the object has no tag before resetting top. | 822 // Make sure the object has no tag before resetting top. |
813 and_(Operand(object), Immediate(~kHeapObjectTagMask)); | 823 and_(Operand(object), Immediate(~kHeapObjectTagMask)); |
814 #ifdef DEBUG | 824 #ifdef DEBUG |
815 cmp(object, Operand::StaticVariable(new_space_allocation_top)); | 825 cmp(object, Operand::StaticVariable(new_space_allocation_top)); |
816 Check(below, "Undo allocation of non allocated memory"); | 826 Check(below, "Undo allocation of non allocated memory"); |
817 #endif | 827 #endif |
818 mov(Operand::StaticVariable(new_space_allocation_top), object); | 828 mov(Operand::StaticVariable(new_space_allocation_top), object); |
819 } | 829 } |
820 | 830 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 | 1182 |
1173 | 1183 |
1174 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { | 1184 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { |
1175 CallRuntime(Runtime::FunctionForId(id), num_arguments); | 1185 CallRuntime(Runtime::FunctionForId(id), num_arguments); |
1176 } | 1186 } |
1177 | 1187 |
1178 | 1188 |
1179 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { | 1189 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
1180 const Runtime::Function* function = Runtime::FunctionForId(id); | 1190 const Runtime::Function* function = Runtime::FunctionForId(id); |
1181 Set(eax, Immediate(function->nargs)); | 1191 Set(eax, Immediate(function->nargs)); |
1182 mov(ebx, Immediate(ExternalReference(function))); | 1192 mov(ebx, Immediate(ExternalReference(function, isolate()))); |
1183 CEntryStub ces(1); | 1193 CEntryStub ces(1); |
1184 ces.SaveDoubles(); | 1194 ces.SaveDoubles(); |
1185 CallStub(&ces); | 1195 CallStub(&ces); |
1186 } | 1196 } |
1187 | 1197 |
1188 | 1198 |
1189 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, | 1199 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, |
1190 int num_arguments) { | 1200 int num_arguments) { |
1191 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); | 1201 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); |
1192 } | 1202 } |
1193 | 1203 |
1194 | 1204 |
1195 void MacroAssembler::CallRuntime(const Runtime::Function* f, | 1205 void MacroAssembler::CallRuntime(const Runtime::Function* f, |
1196 int num_arguments) { | 1206 int num_arguments) { |
1197 // If the expected number of arguments of the runtime function is | 1207 // If the expected number of arguments of the runtime function is |
1198 // constant, we check that the actual number of arguments match the | 1208 // constant, we check that the actual number of arguments match the |
1199 // expectation. | 1209 // expectation. |
1200 if (f->nargs >= 0 && f->nargs != num_arguments) { | 1210 if (f->nargs >= 0 && f->nargs != num_arguments) { |
1201 IllegalOperation(num_arguments); | 1211 IllegalOperation(num_arguments); |
1202 return; | 1212 return; |
1203 } | 1213 } |
1204 | 1214 |
1205 // TODO(1236192): Most runtime routines don't need the number of | 1215 // TODO(1236192): Most runtime routines don't need the number of |
1206 // arguments passed in because it is constant. At some point we | 1216 // arguments passed in because it is constant. At some point we |
1207 // should remove this need and make the runtime routine entry code | 1217 // should remove this need and make the runtime routine entry code |
1208 // smarter. | 1218 // smarter. |
1209 Set(eax, Immediate(num_arguments)); | 1219 Set(eax, Immediate(num_arguments)); |
1210 mov(ebx, Immediate(ExternalReference(f))); | 1220 mov(ebx, Immediate(ExternalReference(f, isolate()))); |
1211 CEntryStub ces(1); | 1221 CEntryStub ces(1); |
1212 CallStub(&ces); | 1222 CallStub(&ces); |
1213 } | 1223 } |
1214 | 1224 |
1215 | 1225 |
1216 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, | 1226 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, |
1217 int num_arguments) { | 1227 int num_arguments) { |
1218 if (f->nargs >= 0 && f->nargs != num_arguments) { | 1228 if (f->nargs >= 0 && f->nargs != num_arguments) { |
1219 IllegalOperation(num_arguments); | 1229 IllegalOperation(num_arguments); |
1220 // Since we did not call the stub, there was no allocation failure. | 1230 // Since we did not call the stub, there was no allocation failure. |
1221 // Return some non-failure object. | 1231 // Return some non-failure object. |
1222 return HEAP->undefined_value(); | 1232 return HEAP->undefined_value(); |
1223 } | 1233 } |
1224 | 1234 |
1225 // TODO(1236192): Most runtime routines don't need the number of | 1235 // TODO(1236192): Most runtime routines don't need the number of |
1226 // arguments passed in because it is constant. At some point we | 1236 // arguments passed in because it is constant. At some point we |
1227 // should remove this need and make the runtime routine entry code | 1237 // should remove this need and make the runtime routine entry code |
1228 // smarter. | 1238 // smarter. |
1229 Set(eax, Immediate(num_arguments)); | 1239 Set(eax, Immediate(num_arguments)); |
1230 mov(ebx, Immediate(ExternalReference(f))); | 1240 mov(ebx, Immediate(ExternalReference(f, isolate()))); |
1231 CEntryStub ces(1); | 1241 CEntryStub ces(1); |
1232 return TryCallStub(&ces); | 1242 return TryCallStub(&ces); |
1233 } | 1243 } |
1234 | 1244 |
1235 | 1245 |
1236 void MacroAssembler::CallExternalReference(ExternalReference ref, | 1246 void MacroAssembler::CallExternalReference(ExternalReference ref, |
1237 int num_arguments) { | 1247 int num_arguments) { |
1238 mov(eax, Immediate(num_arguments)); | 1248 mov(eax, Immediate(num_arguments)); |
1239 mov(ebx, Immediate(ref)); | 1249 mov(ebx, Immediate(ref)); |
1240 | 1250 |
(...skipping 21 matching lines...) Expand all Loading... |
1262 // should remove this need and make the runtime routine entry code | 1272 // should remove this need and make the runtime routine entry code |
1263 // smarter. | 1273 // smarter. |
1264 Set(eax, Immediate(num_arguments)); | 1274 Set(eax, Immediate(num_arguments)); |
1265 return TryJumpToExternalReference(ext); | 1275 return TryJumpToExternalReference(ext); |
1266 } | 1276 } |
1267 | 1277 |
1268 | 1278 |
1269 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, | 1279 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
1270 int num_arguments, | 1280 int num_arguments, |
1271 int result_size) { | 1281 int result_size) { |
1272 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); | 1282 TailCallExternalReference(ExternalReference(fid, isolate()), |
| 1283 num_arguments, |
| 1284 result_size); |
1273 } | 1285 } |
1274 | 1286 |
1275 | 1287 |
1276 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid, | 1288 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid, |
1277 int num_arguments, | 1289 int num_arguments, |
1278 int result_size) { | 1290 int result_size) { |
1279 return TryTailCallExternalReference( | 1291 return TryTailCallExternalReference( |
1280 ExternalReference(fid), num_arguments, result_size); | 1292 ExternalReference(fid, isolate()), num_arguments, result_size); |
1281 } | 1293 } |
1282 | 1294 |
1283 | 1295 |
1284 // If true, a Handle<T> returned by value from a function with cdecl calling | 1296 // If true, a Handle<T> returned by value from a function with cdecl calling |
1285 // convention will be returned directly as a value of location_ field in a | 1297 // convention will be returned directly as a value of location_ field in a |
1286 // register eax. | 1298 // register eax. |
1287 // If false, it is returned as a pointer to a preallocated by caller memory | 1299 // If false, it is returned as a pointer to a preallocated by caller memory |
1288 // region. Pointer to this region should be passed to a function as an | 1300 // region. Pointer to this region should be passed to a function as an |
1289 // implicit first argument. | 1301 // implicit first argument. |
1290 #if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__) | 1302 #if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 // previous handle scope. | 1382 // previous handle scope. |
1371 mov(Operand::StaticVariable(next_address), ebx); | 1383 mov(Operand::StaticVariable(next_address), ebx); |
1372 sub(Operand::StaticVariable(level_address), Immediate(1)); | 1384 sub(Operand::StaticVariable(level_address), Immediate(1)); |
1373 Assert(above_equal, "Invalid HandleScope level"); | 1385 Assert(above_equal, "Invalid HandleScope level"); |
1374 cmp(edi, Operand::StaticVariable(limit_address)); | 1386 cmp(edi, Operand::StaticVariable(limit_address)); |
1375 j(not_equal, &delete_allocated_handles, not_taken); | 1387 j(not_equal, &delete_allocated_handles, not_taken); |
1376 bind(&leave_exit_frame); | 1388 bind(&leave_exit_frame); |
1377 | 1389 |
1378 // Check if the function scheduled an exception. | 1390 // Check if the function scheduled an exception. |
1379 ExternalReference scheduled_exception_address = | 1391 ExternalReference scheduled_exception_address = |
1380 ExternalReference::scheduled_exception_address(); | 1392 ExternalReference::scheduled_exception_address(isolate()); |
1381 cmp(Operand::StaticVariable(scheduled_exception_address), | 1393 cmp(Operand::StaticVariable(scheduled_exception_address), |
1382 Immediate(FACTORY->the_hole_value())); | 1394 Immediate(isolate()->factory()->the_hole_value())); |
1383 j(not_equal, &promote_scheduled_exception, not_taken); | 1395 j(not_equal, &promote_scheduled_exception, not_taken); |
1384 LeaveApiExitFrame(); | 1396 LeaveApiExitFrame(); |
1385 ret(stack_space * kPointerSize); | 1397 ret(stack_space * kPointerSize); |
1386 bind(&promote_scheduled_exception); | 1398 bind(&promote_scheduled_exception); |
1387 MaybeObject* result = | 1399 MaybeObject* result = |
1388 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 1400 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
1389 if (result->IsFailure()) { | 1401 if (result->IsFailure()) { |
1390 return result; | 1402 return result; |
1391 } | 1403 } |
1392 bind(&empty_handle); | 1404 bind(&empty_handle); |
1393 // It was zero; the result is undefined. | 1405 // It was zero; the result is undefined. |
1394 mov(eax, FACTORY->undefined_value()); | 1406 mov(eax, FACTORY->undefined_value()); |
1395 jmp(&prologue); | 1407 jmp(&prologue); |
1396 | 1408 |
1397 // HandleScope limit has changed. Delete allocated extensions. | 1409 // HandleScope limit has changed. Delete allocated extensions. |
| 1410 ExternalReference delete_extensions = |
| 1411 ExternalReference::delete_handle_scope_extensions(isolate()); |
1398 bind(&delete_allocated_handles); | 1412 bind(&delete_allocated_handles); |
1399 mov(Operand::StaticVariable(limit_address), edi); | 1413 mov(Operand::StaticVariable(limit_address), edi); |
1400 mov(edi, eax); | 1414 mov(edi, eax); |
1401 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); | 1415 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); |
1402 mov(eax, Immediate(ExternalReference::delete_handle_scope_extensions())); | 1416 mov(eax, Immediate(delete_extensions)); |
1403 call(Operand(eax)); | 1417 call(Operand(eax)); |
1404 mov(eax, edi); | 1418 mov(eax, edi); |
1405 jmp(&leave_exit_frame); | 1419 jmp(&leave_exit_frame); |
1406 | 1420 |
1407 return result; | 1421 return result; |
1408 } | 1422 } |
1409 | 1423 |
1410 | 1424 |
1411 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { | 1425 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { |
1412 // Set the entry point and jump to the C entry runtime stub. | 1426 // Set the entry point and jump to the C entry runtime stub. |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2036 | 2050 |
2037 // Check that the code was patched as expected. | 2051 // Check that the code was patched as expected. |
2038 ASSERT(masm_.pc_ == address_ + size_); | 2052 ASSERT(masm_.pc_ == address_ + size_); |
2039 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2053 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2040 } | 2054 } |
2041 | 2055 |
2042 | 2056 |
2043 } } // namespace v8::internal | 2057 } } // namespace v8::internal |
2044 | 2058 |
2045 #endif // V8_TARGET_ARCH_IA32 | 2059 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |