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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 386 |
387 | 387 |
388 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { | 388 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { |
389 CallRuntime(Runtime::FunctionForId(id), num_arguments); | 389 CallRuntime(Runtime::FunctionForId(id), num_arguments); |
390 } | 390 } |
391 | 391 |
392 | 392 |
393 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { | 393 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
394 const Runtime::Function* function = Runtime::FunctionForId(id); | 394 const Runtime::Function* function = Runtime::FunctionForId(id); |
395 Set(rax, function->nargs); | 395 Set(rax, function->nargs); |
396 movq(rbx, ExternalReference(function)); | 396 movq(rbx, ExternalReference(function, isolate())); |
397 CEntryStub ces(1); | 397 CEntryStub ces(1); |
398 ces.SaveDoubles(); | 398 ces.SaveDoubles(); |
399 CallStub(&ces); | 399 CallStub(&ces); |
400 } | 400 } |
401 | 401 |
402 | 402 |
403 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, | 403 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, |
404 int num_arguments) { | 404 int num_arguments) { |
405 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); | 405 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); |
406 } | 406 } |
407 | 407 |
408 | 408 |
409 void MacroAssembler::CallRuntime(const Runtime::Function* f, | 409 void MacroAssembler::CallRuntime(const Runtime::Function* f, |
410 int num_arguments) { | 410 int num_arguments) { |
411 // If the expected number of arguments of the runtime function is | 411 // If the expected number of arguments of the runtime function is |
412 // constant, we check that the actual number of arguments match the | 412 // constant, we check that the actual number of arguments match the |
413 // expectation. | 413 // expectation. |
414 if (f->nargs >= 0 && f->nargs != num_arguments) { | 414 if (f->nargs >= 0 && f->nargs != num_arguments) { |
415 IllegalOperation(num_arguments); | 415 IllegalOperation(num_arguments); |
416 return; | 416 return; |
417 } | 417 } |
418 | 418 |
419 // TODO(1236192): Most runtime routines don't need the number of | 419 // TODO(1236192): Most runtime routines don't need the number of |
420 // arguments passed in because it is constant. At some point we | 420 // arguments passed in because it is constant. At some point we |
421 // should remove this need and make the runtime routine entry code | 421 // should remove this need and make the runtime routine entry code |
422 // smarter. | 422 // smarter. |
423 Set(rax, num_arguments); | 423 Set(rax, num_arguments); |
424 movq(rbx, ExternalReference(f)); | 424 movq(rbx, ExternalReference(f, isolate())); |
425 CEntryStub ces(f->result_size); | 425 CEntryStub ces(f->result_size); |
426 CallStub(&ces); | 426 CallStub(&ces); |
427 } | 427 } |
428 | 428 |
429 | 429 |
430 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, | 430 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, |
431 int num_arguments) { | 431 int num_arguments) { |
432 if (f->nargs >= 0 && f->nargs != num_arguments) { | 432 if (f->nargs >= 0 && f->nargs != num_arguments) { |
433 IllegalOperation(num_arguments); | 433 IllegalOperation(num_arguments); |
434 // Since we did not call the stub, there was no allocation failure. | 434 // Since we did not call the stub, there was no allocation failure. |
435 // Return some non-failure object. | 435 // Return some non-failure object. |
436 return HEAP->undefined_value(); | 436 return HEAP->undefined_value(); |
437 } | 437 } |
438 | 438 |
439 // TODO(1236192): Most runtime routines don't need the number of | 439 // TODO(1236192): Most runtime routines don't need the number of |
440 // arguments passed in because it is constant. At some point we | 440 // arguments passed in because it is constant. At some point we |
441 // should remove this need and make the runtime routine entry code | 441 // should remove this need and make the runtime routine entry code |
442 // smarter. | 442 // smarter. |
443 Set(rax, num_arguments); | 443 Set(rax, num_arguments); |
444 movq(rbx, ExternalReference(f)); | 444 movq(rbx, ExternalReference(f, isolate())); |
445 CEntryStub ces(f->result_size); | 445 CEntryStub ces(f->result_size); |
446 return TryCallStub(&ces); | 446 return TryCallStub(&ces); |
447 } | 447 } |
448 | 448 |
449 | 449 |
450 void MacroAssembler::CallExternalReference(const ExternalReference& ext, | 450 void MacroAssembler::CallExternalReference(const ExternalReference& ext, |
451 int num_arguments) { | 451 int num_arguments) { |
452 Set(rax, num_arguments); | 452 Set(rax, num_arguments); |
453 movq(rbx, ext); | 453 movq(rbx, ext); |
454 | 454 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 // should remove this need and make the runtime routine entry code | 490 // should remove this need and make the runtime routine entry code |
491 // smarter. | 491 // smarter. |
492 Set(rax, num_arguments); | 492 Set(rax, num_arguments); |
493 return TryJumpToExternalReference(ext, result_size); | 493 return TryJumpToExternalReference(ext, result_size); |
494 } | 494 } |
495 | 495 |
496 | 496 |
497 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, | 497 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
498 int num_arguments, | 498 int num_arguments, |
499 int result_size) { | 499 int result_size) { |
500 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); | 500 TailCallExternalReference(ExternalReference(fid, isolate()), |
| 501 num_arguments, |
| 502 result_size); |
501 } | 503 } |
502 | 504 |
503 | 505 |
504 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid, | 506 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid, |
505 int num_arguments, | 507 int num_arguments, |
506 int result_size) { | 508 int result_size) { |
507 return TryTailCallExternalReference(ExternalReference(fid), | 509 return TryTailCallExternalReference(ExternalReference(fid, isolate()), |
508 num_arguments, | 510 num_arguments, |
509 result_size); | 511 result_size); |
510 } | 512 } |
511 | 513 |
512 | 514 |
513 static int Offset(ExternalReference ref0, ExternalReference ref1) { | 515 static int Offset(ExternalReference ref0, ExternalReference ref1) { |
514 int64_t offset = (ref0.address() - ref1.address()); | 516 int64_t offset = (ref0.address() - ref1.address()); |
515 // Check that fits into int. | 517 // Check that fits into int. |
516 ASSERT(static_cast<int>(offset) == offset); | 518 ASSERT(static_cast<int>(offset) == offset); |
517 return static_cast<int>(offset); | 519 return static_cast<int>(offset); |
(...skipping 26 matching lines...) Expand all Loading... |
544 ExternalReference next_address = | 546 ExternalReference next_address = |
545 ExternalReference::handle_scope_next_address(); | 547 ExternalReference::handle_scope_next_address(); |
546 const int kNextOffset = 0; | 548 const int kNextOffset = 0; |
547 const int kLimitOffset = Offset( | 549 const int kLimitOffset = Offset( |
548 ExternalReference::handle_scope_limit_address(), | 550 ExternalReference::handle_scope_limit_address(), |
549 next_address); | 551 next_address); |
550 const int kLevelOffset = Offset( | 552 const int kLevelOffset = Offset( |
551 ExternalReference::handle_scope_level_address(), | 553 ExternalReference::handle_scope_level_address(), |
552 next_address); | 554 next_address); |
553 ExternalReference scheduled_exception_address = | 555 ExternalReference scheduled_exception_address = |
554 ExternalReference::scheduled_exception_address(); | 556 ExternalReference::scheduled_exception_address(isolate()); |
555 | 557 |
556 // Allocate HandleScope in callee-save registers. | 558 // Allocate HandleScope in callee-save registers. |
557 Register prev_next_address_reg = r14; | 559 Register prev_next_address_reg = r14; |
558 Register prev_limit_reg = rbx; | 560 Register prev_limit_reg = rbx; |
559 Register base_reg = r15; | 561 Register base_reg = r15; |
560 movq(base_reg, next_address); | 562 movq(base_reg, next_address); |
561 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); | 563 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); |
562 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); | 564 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); |
563 addl(Operand(base_reg, kLevelOffset), Immediate(1)); | 565 addl(Operand(base_reg, kLevelOffset), Immediate(1)); |
564 // Call the api function! | 566 // Call the api function! |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 | 610 |
609 // HandleScope limit has changed. Delete allocated extensions. | 611 // HandleScope limit has changed. Delete allocated extensions. |
610 bind(&delete_allocated_handles); | 612 bind(&delete_allocated_handles); |
611 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); | 613 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); |
612 movq(prev_limit_reg, rax); | 614 movq(prev_limit_reg, rax); |
613 #ifdef _WIN64 | 615 #ifdef _WIN64 |
614 movq(rcx, ExternalReference::isolate_address()); | 616 movq(rcx, ExternalReference::isolate_address()); |
615 #else | 617 #else |
616 movq(rdi, ExternalReference::isolate_address()); | 618 movq(rdi, ExternalReference::isolate_address()); |
617 #endif | 619 #endif |
618 movq(rax, ExternalReference::delete_handle_scope_extensions()); | 620 movq(rax, ExternalReference::delete_handle_scope_extensions(isolate())); |
619 call(rax); | 621 call(rax); |
620 movq(rax, prev_limit_reg); | 622 movq(rax, prev_limit_reg); |
621 jmp(&leave_exit_frame); | 623 jmp(&leave_exit_frame); |
622 | 624 |
623 return result; | 625 return result; |
624 } | 626 } |
625 | 627 |
626 | 628 |
627 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, | 629 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, |
628 int result_size) { | 630 int result_size) { |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 push(rbp); | 1610 push(rbp); |
1609 } else { | 1611 } else { |
1610 ASSERT(try_location == IN_JS_ENTRY); | 1612 ASSERT(try_location == IN_JS_ENTRY); |
1611 // The frame pointer does not point to a JS frame so we save NULL | 1613 // The frame pointer does not point to a JS frame so we save NULL |
1612 // for rbp. We expect the code throwing an exception to check rbp | 1614 // for rbp. We expect the code throwing an exception to check rbp |
1613 // before dereferencing it to restore the context. | 1615 // before dereferencing it to restore the context. |
1614 push(Immediate(StackHandler::ENTRY)); | 1616 push(Immediate(StackHandler::ENTRY)); |
1615 push(Immediate(0)); // NULL frame pointer. | 1617 push(Immediate(0)); // NULL frame pointer. |
1616 } | 1618 } |
1617 // Save the current handler. | 1619 // Save the current handler. |
1618 movq(kScratchRegister, ExternalReference(Isolate::k_handler_address)); | 1620 movq(kScratchRegister, |
| 1621 ExternalReference(Isolate::k_handler_address, isolate())); |
1619 push(Operand(kScratchRegister, 0)); | 1622 push(Operand(kScratchRegister, 0)); |
1620 // Link this handler. | 1623 // Link this handler. |
1621 movq(Operand(kScratchRegister, 0), rsp); | 1624 movq(Operand(kScratchRegister, 0), rsp); |
1622 } | 1625 } |
1623 | 1626 |
1624 | 1627 |
1625 void MacroAssembler::PopTryHandler() { | 1628 void MacroAssembler::PopTryHandler() { |
1626 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 1629 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
1627 // Unlink this handler. | 1630 // Unlink this handler. |
1628 movq(kScratchRegister, ExternalReference(Isolate::k_handler_address)); | 1631 movq(kScratchRegister, |
| 1632 ExternalReference(Isolate::k_handler_address, isolate())); |
1629 pop(Operand(kScratchRegister, 0)); | 1633 pop(Operand(kScratchRegister, 0)); |
1630 // Remove the remaining fields. | 1634 // Remove the remaining fields. |
1631 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 1635 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
1632 } | 1636 } |
1633 | 1637 |
1634 | 1638 |
1635 void MacroAssembler::Throw(Register value) { | 1639 void MacroAssembler::Throw(Register value) { |
1636 // Check that stack should contain next handler, frame pointer, state and | 1640 // Check that stack should contain next handler, frame pointer, state and |
1637 // return address in that order. | 1641 // return address in that order. |
1638 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == | 1642 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == |
1639 StackHandlerConstants::kStateOffset); | 1643 StackHandlerConstants::kStateOffset); |
1640 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == | 1644 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == |
1641 StackHandlerConstants::kPCOffset); | 1645 StackHandlerConstants::kPCOffset); |
1642 // Keep thrown value in rax. | 1646 // Keep thrown value in rax. |
1643 if (!value.is(rax)) { | 1647 if (!value.is(rax)) { |
1644 movq(rax, value); | 1648 movq(rax, value); |
1645 } | 1649 } |
1646 | 1650 |
1647 ExternalReference handler_address(Isolate::k_handler_address); | 1651 ExternalReference handler_address(Isolate::k_handler_address, isolate()); |
1648 movq(kScratchRegister, handler_address); | 1652 movq(kScratchRegister, handler_address); |
1649 movq(rsp, Operand(kScratchRegister, 0)); | 1653 movq(rsp, Operand(kScratchRegister, 0)); |
1650 // get next in chain | 1654 // get next in chain |
1651 pop(rcx); | 1655 pop(rcx); |
1652 movq(Operand(kScratchRegister, 0), rcx); | 1656 movq(Operand(kScratchRegister, 0), rcx); |
1653 pop(rbp); // pop frame pointer | 1657 pop(rbp); // pop frame pointer |
1654 pop(rdx); // remove state | 1658 pop(rdx); // remove state |
1655 | 1659 |
1656 // Before returning we restore the context from the frame pointer if not NULL. | 1660 // Before returning we restore the context from the frame pointer if not NULL. |
1657 // The frame pointer is NULL in the exception handler of a JS entry frame. | 1661 // The frame pointer is NULL in the exception handler of a JS entry frame. |
1658 Set(rsi, 0); // Tentatively set context pointer to NULL | 1662 Set(rsi, 0); // Tentatively set context pointer to NULL |
1659 NearLabel skip; | 1663 NearLabel skip; |
1660 cmpq(rbp, Immediate(0)); | 1664 cmpq(rbp, Immediate(0)); |
1661 j(equal, &skip); | 1665 j(equal, &skip); |
1662 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1666 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1663 bind(&skip); | 1667 bind(&skip); |
1664 ret(0); | 1668 ret(0); |
1665 } | 1669 } |
1666 | 1670 |
1667 | 1671 |
1668 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 1672 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
1669 Register value) { | 1673 Register value) { |
1670 // Keep thrown value in rax. | 1674 // Keep thrown value in rax. |
1671 if (!value.is(rax)) { | 1675 if (!value.is(rax)) { |
1672 movq(rax, value); | 1676 movq(rax, value); |
1673 } | 1677 } |
1674 // Fetch top stack handler. | 1678 // Fetch top stack handler. |
1675 ExternalReference handler_address(Isolate::k_handler_address); | 1679 ExternalReference handler_address(Isolate::k_handler_address, isolate()); |
1676 movq(kScratchRegister, handler_address); | 1680 movq(kScratchRegister, handler_address); |
1677 movq(rsp, Operand(kScratchRegister, 0)); | 1681 movq(rsp, Operand(kScratchRegister, 0)); |
1678 | 1682 |
1679 // Unwind the handlers until the ENTRY handler is found. | 1683 // Unwind the handlers until the ENTRY handler is found. |
1680 NearLabel loop, done; | 1684 NearLabel loop, done; |
1681 bind(&loop); | 1685 bind(&loop); |
1682 // Load the type of the current stack handler. | 1686 // Load the type of the current stack handler. |
1683 const int kStateOffset = StackHandlerConstants::kStateOffset; | 1687 const int kStateOffset = StackHandlerConstants::kStateOffset; |
1684 cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY)); | 1688 cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY)); |
1685 j(equal, &done); | 1689 j(equal, &done); |
1686 // Fetch the next handler in the list. | 1690 // Fetch the next handler in the list. |
1687 const int kNextOffset = StackHandlerConstants::kNextOffset; | 1691 const int kNextOffset = StackHandlerConstants::kNextOffset; |
1688 movq(rsp, Operand(rsp, kNextOffset)); | 1692 movq(rsp, Operand(rsp, kNextOffset)); |
1689 jmp(&loop); | 1693 jmp(&loop); |
1690 bind(&done); | 1694 bind(&done); |
1691 | 1695 |
1692 // Set the top handler address to next handler past the current ENTRY handler. | 1696 // Set the top handler address to next handler past the current ENTRY handler. |
1693 movq(kScratchRegister, handler_address); | 1697 movq(kScratchRegister, handler_address); |
1694 pop(Operand(kScratchRegister, 0)); | 1698 pop(Operand(kScratchRegister, 0)); |
1695 | 1699 |
1696 if (type == OUT_OF_MEMORY) { | 1700 if (type == OUT_OF_MEMORY) { |
1697 // Set external caught exception to false. | 1701 // Set external caught exception to false. |
1698 ExternalReference external_caught( | 1702 ExternalReference external_caught( |
1699 Isolate::k_external_caught_exception_address); | 1703 Isolate::k_external_caught_exception_address, isolate()); |
1700 movq(rax, Immediate(false)); | 1704 movq(rax, Immediate(false)); |
1701 store_rax(external_caught); | 1705 store_rax(external_caught); |
1702 | 1706 |
1703 // Set pending exception and rax to out of memory exception. | 1707 // Set pending exception and rax to out of memory exception. |
1704 ExternalReference pending_exception(Isolate::k_pending_exception_address); | 1708 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 1709 isolate()); |
1705 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); | 1710 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); |
1706 store_rax(pending_exception); | 1711 store_rax(pending_exception); |
1707 } | 1712 } |
1708 | 1713 |
1709 // Clear the context pointer. | 1714 // Clear the context pointer. |
1710 Set(rsi, 0); | 1715 Set(rsi, 0); |
1711 | 1716 |
1712 // Restore registers from handler. | 1717 // Restore registers from handler. |
1713 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == | 1718 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == |
1714 StackHandlerConstants::kFPOffset); | 1719 StackHandlerConstants::kFPOffset); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 subl(operand, Immediate(value)); | 1919 subl(operand, Immediate(value)); |
1915 } | 1920 } |
1916 } | 1921 } |
1917 } | 1922 } |
1918 | 1923 |
1919 | 1924 |
1920 #ifdef ENABLE_DEBUGGER_SUPPORT | 1925 #ifdef ENABLE_DEBUGGER_SUPPORT |
1921 void MacroAssembler::DebugBreak() { | 1926 void MacroAssembler::DebugBreak() { |
1922 ASSERT(allow_stub_calls()); | 1927 ASSERT(allow_stub_calls()); |
1923 Set(rax, 0); // No arguments. | 1928 Set(rax, 0); // No arguments. |
1924 movq(rbx, ExternalReference(Runtime::kDebugBreak)); | 1929 movq(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); |
1925 CEntryStub ces(1); | 1930 CEntryStub ces(1); |
1926 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1931 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
1927 } | 1932 } |
1928 #endif // ENABLE_DEBUGGER_SUPPORT | 1933 #endif // ENABLE_DEBUGGER_SUPPORT |
1929 | 1934 |
1930 | 1935 |
1931 void MacroAssembler::InvokeCode(Register code, | 1936 void MacroAssembler::InvokeCode(Register code, |
1932 const ParameterCount& expected, | 1937 const ParameterCount& expected, |
1933 const ParameterCount& actual, | 1938 const ParameterCount& actual, |
1934 InvokeFlag flag, | 1939 InvokeFlag flag, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 2073 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
2069 push(Immediate(0)); // Saved entry sp, patched before call. | 2074 push(Immediate(0)); // Saved entry sp, patched before call. |
2070 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 2075 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
2071 push(kScratchRegister); // Accessed from EditFrame::code_slot. | 2076 push(kScratchRegister); // Accessed from EditFrame::code_slot. |
2072 | 2077 |
2073 // Save the frame pointer and the context in top. | 2078 // Save the frame pointer and the context in top. |
2074 if (save_rax) { | 2079 if (save_rax) { |
2075 movq(r14, rax); // Backup rax in callee-save register. | 2080 movq(r14, rax); // Backup rax in callee-save register. |
2076 } | 2081 } |
2077 | 2082 |
2078 movq(kScratchRegister, ExternalReference(Isolate::k_c_entry_fp_address)); | 2083 movq(kScratchRegister, |
| 2084 ExternalReference(Isolate::k_c_entry_fp_address, isolate())); |
2079 movq(Operand(kScratchRegister, 0), rbp); | 2085 movq(Operand(kScratchRegister, 0), rbp); |
2080 | 2086 |
2081 movq(kScratchRegister, ExternalReference(Isolate::k_context_address)); | 2087 movq(kScratchRegister, |
| 2088 ExternalReference(Isolate::k_context_address, isolate())); |
2082 movq(Operand(kScratchRegister, 0), rsi); | 2089 movq(Operand(kScratchRegister, 0), rsi); |
2083 } | 2090 } |
2084 | 2091 |
2085 | 2092 |
2086 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, | 2093 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, |
2087 bool save_doubles) { | 2094 bool save_doubles) { |
2088 #ifdef _WIN64 | 2095 #ifdef _WIN64 |
2089 const int kShadowSpace = 4; | 2096 const int kShadowSpace = 4; |
2090 arg_stack_space += kShadowSpace; | 2097 arg_stack_space += kShadowSpace; |
2091 #endif | 2098 #endif |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 void MacroAssembler::LeaveApiExitFrame() { | 2170 void MacroAssembler::LeaveApiExitFrame() { |
2164 movq(rsp, rbp); | 2171 movq(rsp, rbp); |
2165 pop(rbp); | 2172 pop(rbp); |
2166 | 2173 |
2167 LeaveExitFrameEpilogue(); | 2174 LeaveExitFrameEpilogue(); |
2168 } | 2175 } |
2169 | 2176 |
2170 | 2177 |
2171 void MacroAssembler::LeaveExitFrameEpilogue() { | 2178 void MacroAssembler::LeaveExitFrameEpilogue() { |
2172 // Restore current context from top and clear it in debug mode. | 2179 // Restore current context from top and clear it in debug mode. |
2173 ExternalReference context_address(Isolate::k_context_address); | 2180 ExternalReference context_address(Isolate::k_context_address, isolate()); |
2174 movq(kScratchRegister, context_address); | 2181 movq(kScratchRegister, context_address); |
2175 movq(rsi, Operand(kScratchRegister, 0)); | 2182 movq(rsi, Operand(kScratchRegister, 0)); |
2176 #ifdef DEBUG | 2183 #ifdef DEBUG |
2177 movq(Operand(kScratchRegister, 0), Immediate(0)); | 2184 movq(Operand(kScratchRegister, 0), Immediate(0)); |
2178 #endif | 2185 #endif |
2179 | 2186 |
2180 // Clear the top frame. | 2187 // Clear the top frame. |
2181 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); | 2188 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, |
| 2189 isolate()); |
2182 movq(kScratchRegister, c_entry_fp_address); | 2190 movq(kScratchRegister, c_entry_fp_address); |
2183 movq(Operand(kScratchRegister, 0), Immediate(0)); | 2191 movq(Operand(kScratchRegister, 0), Immediate(0)); |
2184 } | 2192 } |
2185 | 2193 |
2186 | 2194 |
2187 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 2195 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
2188 Register scratch, | 2196 Register scratch, |
2189 Label* miss) { | 2197 Label* miss) { |
2190 Label same_contexts; | 2198 Label same_contexts; |
2191 | 2199 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2244 j(not_equal, miss); | 2252 j(not_equal, miss); |
2245 | 2253 |
2246 bind(&same_contexts); | 2254 bind(&same_contexts); |
2247 } | 2255 } |
2248 | 2256 |
2249 | 2257 |
2250 void MacroAssembler::LoadAllocationTopHelper(Register result, | 2258 void MacroAssembler::LoadAllocationTopHelper(Register result, |
2251 Register scratch, | 2259 Register scratch, |
2252 AllocationFlags flags) { | 2260 AllocationFlags flags) { |
2253 ExternalReference new_space_allocation_top = | 2261 ExternalReference new_space_allocation_top = |
2254 ExternalReference::new_space_allocation_top_address(); | 2262 ExternalReference::new_space_allocation_top_address(isolate()); |
2255 | 2263 |
2256 // Just return if allocation top is already known. | 2264 // Just return if allocation top is already known. |
2257 if ((flags & RESULT_CONTAINS_TOP) != 0) { | 2265 if ((flags & RESULT_CONTAINS_TOP) != 0) { |
2258 // No use of scratch if allocation top is provided. | 2266 // No use of scratch if allocation top is provided. |
2259 ASSERT(!scratch.is_valid()); | 2267 ASSERT(!scratch.is_valid()); |
2260 #ifdef DEBUG | 2268 #ifdef DEBUG |
2261 // Assert that result actually contains top on entry. | 2269 // Assert that result actually contains top on entry. |
2262 movq(kScratchRegister, new_space_allocation_top); | 2270 movq(kScratchRegister, new_space_allocation_top); |
2263 cmpq(result, Operand(kScratchRegister, 0)); | 2271 cmpq(result, Operand(kScratchRegister, 0)); |
2264 Check(equal, "Unexpected allocation top"); | 2272 Check(equal, "Unexpected allocation top"); |
(...skipping 16 matching lines...) Expand all Loading... |
2281 | 2289 |
2282 | 2290 |
2283 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, | 2291 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, |
2284 Register scratch) { | 2292 Register scratch) { |
2285 if (emit_debug_code()) { | 2293 if (emit_debug_code()) { |
2286 testq(result_end, Immediate(kObjectAlignmentMask)); | 2294 testq(result_end, Immediate(kObjectAlignmentMask)); |
2287 Check(zero, "Unaligned allocation in new space"); | 2295 Check(zero, "Unaligned allocation in new space"); |
2288 } | 2296 } |
2289 | 2297 |
2290 ExternalReference new_space_allocation_top = | 2298 ExternalReference new_space_allocation_top = |
2291 ExternalReference::new_space_allocation_top_address(); | 2299 ExternalReference::new_space_allocation_top_address(isolate()); |
2292 | 2300 |
2293 // Update new top. | 2301 // Update new top. |
2294 if (result_end.is(rax)) { | 2302 if (result_end.is(rax)) { |
2295 // rax can be stored directly to a memory location. | 2303 // rax can be stored directly to a memory location. |
2296 store_rax(new_space_allocation_top); | 2304 store_rax(new_space_allocation_top); |
2297 } else { | 2305 } else { |
2298 // Register required - use scratch provided if available. | 2306 // Register required - use scratch provided if available. |
2299 if (scratch.is_valid()) { | 2307 if (scratch.is_valid()) { |
2300 movq(Operand(scratch, 0), result_end); | 2308 movq(Operand(scratch, 0), result_end); |
2301 } else { | 2309 } else { |
(...skipping 24 matching lines...) Expand all Loading... |
2326 jmp(gc_required); | 2334 jmp(gc_required); |
2327 return; | 2335 return; |
2328 } | 2336 } |
2329 ASSERT(!result.is(result_end)); | 2337 ASSERT(!result.is(result_end)); |
2330 | 2338 |
2331 // Load address of new object into result. | 2339 // Load address of new object into result. |
2332 LoadAllocationTopHelper(result, scratch, flags); | 2340 LoadAllocationTopHelper(result, scratch, flags); |
2333 | 2341 |
2334 // Calculate new top and bail out if new space is exhausted. | 2342 // Calculate new top and bail out if new space is exhausted. |
2335 ExternalReference new_space_allocation_limit = | 2343 ExternalReference new_space_allocation_limit = |
2336 ExternalReference::new_space_allocation_limit_address(); | 2344 ExternalReference::new_space_allocation_limit_address(isolate()); |
2337 | 2345 |
2338 Register top_reg = result_end.is_valid() ? result_end : result; | 2346 Register top_reg = result_end.is_valid() ? result_end : result; |
2339 | 2347 |
2340 if (!top_reg.is(result)) { | 2348 if (!top_reg.is(result)) { |
2341 movq(top_reg, result); | 2349 movq(top_reg, result); |
2342 } | 2350 } |
2343 addq(top_reg, Immediate(object_size)); | 2351 addq(top_reg, Immediate(object_size)); |
2344 j(carry, gc_required); | 2352 j(carry, gc_required); |
2345 movq(kScratchRegister, new_space_allocation_limit); | 2353 movq(kScratchRegister, new_space_allocation_limit); |
2346 cmpq(top_reg, Operand(kScratchRegister, 0)); | 2354 cmpq(top_reg, Operand(kScratchRegister, 0)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2383 jmp(gc_required); | 2391 jmp(gc_required); |
2384 return; | 2392 return; |
2385 } | 2393 } |
2386 ASSERT(!result.is(result_end)); | 2394 ASSERT(!result.is(result_end)); |
2387 | 2395 |
2388 // Load address of new object into result. | 2396 // Load address of new object into result. |
2389 LoadAllocationTopHelper(result, scratch, flags); | 2397 LoadAllocationTopHelper(result, scratch, flags); |
2390 | 2398 |
2391 // Calculate new top and bail out if new space is exhausted. | 2399 // Calculate new top and bail out if new space is exhausted. |
2392 ExternalReference new_space_allocation_limit = | 2400 ExternalReference new_space_allocation_limit = |
2393 ExternalReference::new_space_allocation_limit_address(); | 2401 ExternalReference::new_space_allocation_limit_address(isolate()); |
2394 | 2402 |
2395 // We assume that element_count*element_size + header_size does not | 2403 // We assume that element_count*element_size + header_size does not |
2396 // overflow. | 2404 // overflow. |
2397 lea(result_end, Operand(element_count, element_size, header_size)); | 2405 lea(result_end, Operand(element_count, element_size, header_size)); |
2398 addq(result_end, result); | 2406 addq(result_end, result); |
2399 j(carry, gc_required); | 2407 j(carry, gc_required); |
2400 movq(kScratchRegister, new_space_allocation_limit); | 2408 movq(kScratchRegister, new_space_allocation_limit); |
2401 cmpq(result_end, Operand(kScratchRegister, 0)); | 2409 cmpq(result_end, Operand(kScratchRegister, 0)); |
2402 j(above, gc_required); | 2410 j(above, gc_required); |
2403 | 2411 |
(...skipping 26 matching lines...) Expand all Loading... |
2430 jmp(gc_required); | 2438 jmp(gc_required); |
2431 return; | 2439 return; |
2432 } | 2440 } |
2433 ASSERT(!result.is(result_end)); | 2441 ASSERT(!result.is(result_end)); |
2434 | 2442 |
2435 // Load address of new object into result. | 2443 // Load address of new object into result. |
2436 LoadAllocationTopHelper(result, scratch, flags); | 2444 LoadAllocationTopHelper(result, scratch, flags); |
2437 | 2445 |
2438 // Calculate new top and bail out if new space is exhausted. | 2446 // Calculate new top and bail out if new space is exhausted. |
2439 ExternalReference new_space_allocation_limit = | 2447 ExternalReference new_space_allocation_limit = |
2440 ExternalReference::new_space_allocation_limit_address(); | 2448 ExternalReference::new_space_allocation_limit_address(isolate()); |
2441 if (!object_size.is(result_end)) { | 2449 if (!object_size.is(result_end)) { |
2442 movq(result_end, object_size); | 2450 movq(result_end, object_size); |
2443 } | 2451 } |
2444 addq(result_end, result); | 2452 addq(result_end, result); |
2445 j(carry, gc_required); | 2453 j(carry, gc_required); |
2446 movq(kScratchRegister, new_space_allocation_limit); | 2454 movq(kScratchRegister, new_space_allocation_limit); |
2447 cmpq(result_end, Operand(kScratchRegister, 0)); | 2455 cmpq(result_end, Operand(kScratchRegister, 0)); |
2448 j(above, gc_required); | 2456 j(above, gc_required); |
2449 | 2457 |
2450 // Update allocation top. | 2458 // Update allocation top. |
2451 UpdateAllocationTopHelper(result_end, scratch); | 2459 UpdateAllocationTopHelper(result_end, scratch); |
2452 | 2460 |
2453 // Tag the result if requested. | 2461 // Tag the result if requested. |
2454 if ((flags & TAG_OBJECT) != 0) { | 2462 if ((flags & TAG_OBJECT) != 0) { |
2455 addq(result, Immediate(kHeapObjectTag)); | 2463 addq(result, Immediate(kHeapObjectTag)); |
2456 } | 2464 } |
2457 } | 2465 } |
2458 | 2466 |
2459 | 2467 |
2460 void MacroAssembler::UndoAllocationInNewSpace(Register object) { | 2468 void MacroAssembler::UndoAllocationInNewSpace(Register object) { |
2461 ExternalReference new_space_allocation_top = | 2469 ExternalReference new_space_allocation_top = |
2462 ExternalReference::new_space_allocation_top_address(); | 2470 ExternalReference::new_space_allocation_top_address(isolate()); |
2463 | 2471 |
2464 // Make sure the object has no tag before resetting top. | 2472 // Make sure the object has no tag before resetting top. |
2465 and_(object, Immediate(~kHeapObjectTagMask)); | 2473 and_(object, Immediate(~kHeapObjectTagMask)); |
2466 movq(kScratchRegister, new_space_allocation_top); | 2474 movq(kScratchRegister, new_space_allocation_top); |
2467 #ifdef DEBUG | 2475 #ifdef DEBUG |
2468 cmpq(object, Operand(kScratchRegister, 0)); | 2476 cmpq(object, Operand(kScratchRegister, 0)); |
2469 Check(below, "Undo allocation of non allocated memory"); | 2477 Check(below, "Undo allocation of non allocated memory"); |
2470 #endif | 2478 #endif |
2471 movq(Operand(kScratchRegister, 0), object); | 2479 movq(Operand(kScratchRegister, 0), object); |
2472 } | 2480 } |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 CPU::FlushICache(address_, size_); | 2766 CPU::FlushICache(address_, size_); |
2759 | 2767 |
2760 // Check that the code was patched as expected. | 2768 // Check that the code was patched as expected. |
2761 ASSERT(masm_.pc_ == address_ + size_); | 2769 ASSERT(masm_.pc_ == address_ + size_); |
2762 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2770 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2763 } | 2771 } |
2764 | 2772 |
2765 } } // namespace v8::internal | 2773 } } // namespace v8::internal |
2766 | 2774 |
2767 #endif // V8_TARGET_ARCH_X64 | 2775 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |