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 2397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2408 ASSERT(try_location == IN_JS_ENTRY); | 2408 ASSERT(try_location == IN_JS_ENTRY); |
2409 // The frame pointer does not point to a JS frame so we save NULL | 2409 // The frame pointer does not point to a JS frame so we save NULL |
2410 // for rbp. We expect the code throwing an exception to check rbp | 2410 // for rbp. We expect the code throwing an exception to check rbp |
2411 // before dereferencing it to restore the context. | 2411 // before dereferencing it to restore the context. |
2412 push(Immediate(StackHandler::ENTRY)); | 2412 push(Immediate(StackHandler::ENTRY)); |
2413 push(Immediate(0)); // NULL frame pointer. | 2413 push(Immediate(0)); // NULL frame pointer. |
2414 Push(Smi::FromInt(0)); // No context. | 2414 Push(Smi::FromInt(0)); // No context. |
2415 } | 2415 } |
2416 // Save the current handler. | 2416 // Save the current handler. |
2417 Operand handler_operand = | 2417 Operand handler_operand = |
2418 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2418 ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate())); |
2419 push(handler_operand); | 2419 push(handler_operand); |
2420 // Link this handler. | 2420 // Link this handler. |
2421 movq(handler_operand, rsp); | 2421 movq(handler_operand, rsp); |
2422 } | 2422 } |
2423 | 2423 |
2424 | 2424 |
2425 void MacroAssembler::PopTryHandler() { | 2425 void MacroAssembler::PopTryHandler() { |
2426 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 2426 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
2427 // Unlink this handler. | 2427 // Unlink this handler. |
2428 Operand handler_operand = | 2428 Operand handler_operand = |
2429 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2429 ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate())); |
2430 pop(handler_operand); | 2430 pop(handler_operand); |
2431 // Remove the remaining fields. | 2431 // Remove the remaining fields. |
2432 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 2432 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
2433 } | 2433 } |
2434 | 2434 |
2435 | 2435 |
2436 void MacroAssembler::Throw(Register value) { | 2436 void MacroAssembler::Throw(Register value) { |
2437 // Adjust this code if not the case. | 2437 // Adjust this code if not the case. |
2438 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 2438 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
2439 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | 2439 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
2440 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); | 2440 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
2441 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 2441 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); | 2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
2443 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); | 2443 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
2444 // Keep thrown value in rax. | 2444 // Keep thrown value in rax. |
2445 if (!value.is(rax)) { | 2445 if (!value.is(rax)) { |
2446 movq(rax, value); | 2446 movq(rax, value); |
2447 } | 2447 } |
2448 | 2448 |
2449 ExternalReference handler_address(Isolate::k_handler_address, isolate()); | 2449 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
2450 Operand handler_operand = ExternalOperand(handler_address); | 2450 Operand handler_operand = ExternalOperand(handler_address); |
2451 movq(rsp, handler_operand); | 2451 movq(rsp, handler_operand); |
2452 // get next in chain | 2452 // get next in chain |
2453 pop(handler_operand); | 2453 pop(handler_operand); |
2454 pop(rsi); // Context. | 2454 pop(rsi); // Context. |
2455 pop(rbp); // Frame pointer. | 2455 pop(rbp); // Frame pointer. |
2456 pop(rdx); // State. | 2456 pop(rdx); // State. |
2457 | 2457 |
2458 // If the handler is a JS frame, restore the context to the frame. | 2458 // If the handler is a JS frame, restore the context to the frame. |
2459 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any | 2459 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any |
(...skipping 15 matching lines...) Expand all Loading... |
2475 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | 2475 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
2476 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); | 2476 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
2477 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 2477 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
2478 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); | 2478 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
2479 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); | 2479 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
2480 // Keep thrown value in rax. | 2480 // Keep thrown value in rax. |
2481 if (!value.is(rax)) { | 2481 if (!value.is(rax)) { |
2482 movq(rax, value); | 2482 movq(rax, value); |
2483 } | 2483 } |
2484 // Fetch top stack handler. | 2484 // Fetch top stack handler. |
2485 ExternalReference handler_address(Isolate::k_handler_address, isolate()); | 2485 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
2486 Load(rsp, handler_address); | 2486 Load(rsp, handler_address); |
2487 | 2487 |
2488 // Unwind the handlers until the ENTRY handler is found. | 2488 // Unwind the handlers until the ENTRY handler is found. |
2489 Label loop, done; | 2489 Label loop, done; |
2490 bind(&loop); | 2490 bind(&loop); |
2491 // Load the type of the current stack handler. | 2491 // Load the type of the current stack handler. |
2492 const int kStateOffset = StackHandlerConstants::kStateOffset; | 2492 const int kStateOffset = StackHandlerConstants::kStateOffset; |
2493 cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY)); | 2493 cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY)); |
2494 j(equal, &done, Label::kNear); | 2494 j(equal, &done, Label::kNear); |
2495 // Fetch the next handler in the list. | 2495 // Fetch the next handler in the list. |
2496 const int kNextOffset = StackHandlerConstants::kNextOffset; | 2496 const int kNextOffset = StackHandlerConstants::kNextOffset; |
2497 movq(rsp, Operand(rsp, kNextOffset)); | 2497 movq(rsp, Operand(rsp, kNextOffset)); |
2498 jmp(&loop); | 2498 jmp(&loop); |
2499 bind(&done); | 2499 bind(&done); |
2500 | 2500 |
2501 // Set the top handler address to next handler past the current ENTRY handler. | 2501 // Set the top handler address to next handler past the current ENTRY handler. |
2502 Operand handler_operand = ExternalOperand(handler_address); | 2502 Operand handler_operand = ExternalOperand(handler_address); |
2503 pop(handler_operand); | 2503 pop(handler_operand); |
2504 | 2504 |
2505 if (type == OUT_OF_MEMORY) { | 2505 if (type == OUT_OF_MEMORY) { |
2506 // Set external caught exception to false. | 2506 // Set external caught exception to false. |
2507 ExternalReference external_caught( | 2507 ExternalReference external_caught( |
2508 Isolate::k_external_caught_exception_address, isolate()); | 2508 Isolate::kExternalCaughtExceptionAddress, isolate()); |
2509 Set(rax, static_cast<int64_t>(false)); | 2509 Set(rax, static_cast<int64_t>(false)); |
2510 Store(external_caught, rax); | 2510 Store(external_caught, rax); |
2511 | 2511 |
2512 // Set pending exception and rax to out of memory exception. | 2512 // Set pending exception and rax to out of memory exception. |
2513 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 2513 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |
2514 isolate()); | 2514 isolate()); |
2515 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); | 2515 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); |
2516 Store(pending_exception, rax); | 2516 Store(pending_exception, rax); |
2517 } | 2517 } |
2518 | 2518 |
2519 // Discard the context saved in the handler and clear the context pointer. | 2519 // Discard the context saved in the handler and clear the context pointer. |
2520 pop(rdx); | 2520 pop(rdx); |
2521 Set(rsi, 0); | 2521 Set(rsi, 0); |
2522 | 2522 |
2523 pop(rbp); // Restore frame pointer. | 2523 pop(rbp); // Restore frame pointer. |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3034 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 3034 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
3035 push(Immediate(0)); // Saved entry sp, patched before call. | 3035 push(Immediate(0)); // Saved entry sp, patched before call. |
3036 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 3036 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
3037 push(kScratchRegister); // Accessed from EditFrame::code_slot. | 3037 push(kScratchRegister); // Accessed from EditFrame::code_slot. |
3038 | 3038 |
3039 // Save the frame pointer and the context in top. | 3039 // Save the frame pointer and the context in top. |
3040 if (save_rax) { | 3040 if (save_rax) { |
3041 movq(r14, rax); // Backup rax in callee-save register. | 3041 movq(r14, rax); // Backup rax in callee-save register. |
3042 } | 3042 } |
3043 | 3043 |
3044 Store(ExternalReference(Isolate::k_c_entry_fp_address, isolate()), rbp); | 3044 Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); |
3045 Store(ExternalReference(Isolate::k_context_address, isolate()), rsi); | 3045 Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); |
3046 } | 3046 } |
3047 | 3047 |
3048 | 3048 |
3049 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, | 3049 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, |
3050 bool save_doubles) { | 3050 bool save_doubles) { |
3051 #ifdef _WIN64 | 3051 #ifdef _WIN64 |
3052 const int kShadowSpace = 4; | 3052 const int kShadowSpace = 4; |
3053 arg_stack_space += kShadowSpace; | 3053 arg_stack_space += kShadowSpace; |
3054 #endif | 3054 #endif |
3055 // Optionally save all XMM registers. | 3055 // Optionally save all XMM registers. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3125 void MacroAssembler::LeaveApiExitFrame() { | 3125 void MacroAssembler::LeaveApiExitFrame() { |
3126 movq(rsp, rbp); | 3126 movq(rsp, rbp); |
3127 pop(rbp); | 3127 pop(rbp); |
3128 | 3128 |
3129 LeaveExitFrameEpilogue(); | 3129 LeaveExitFrameEpilogue(); |
3130 } | 3130 } |
3131 | 3131 |
3132 | 3132 |
3133 void MacroAssembler::LeaveExitFrameEpilogue() { | 3133 void MacroAssembler::LeaveExitFrameEpilogue() { |
3134 // Restore current context from top and clear it in debug mode. | 3134 // Restore current context from top and clear it in debug mode. |
3135 ExternalReference context_address(Isolate::k_context_address, isolate()); | 3135 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
3136 Operand context_operand = ExternalOperand(context_address); | 3136 Operand context_operand = ExternalOperand(context_address); |
3137 movq(rsi, context_operand); | 3137 movq(rsi, context_operand); |
3138 #ifdef DEBUG | 3138 #ifdef DEBUG |
3139 movq(context_operand, Immediate(0)); | 3139 movq(context_operand, Immediate(0)); |
3140 #endif | 3140 #endif |
3141 | 3141 |
3142 // Clear the top frame. | 3142 // Clear the top frame. |
3143 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, | 3143 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, |
3144 isolate()); | 3144 isolate()); |
3145 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); | 3145 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); |
3146 movq(c_entry_fp_operand, Immediate(0)); | 3146 movq(c_entry_fp_operand, Immediate(0)); |
3147 } | 3147 } |
3148 | 3148 |
3149 | 3149 |
3150 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 3150 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
3151 Register scratch, | 3151 Register scratch, |
3152 Label* miss) { | 3152 Label* miss) { |
3153 Label same_contexts; | 3153 Label same_contexts; |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3888 CPU::FlushICache(address_, size_); | 3888 CPU::FlushICache(address_, size_); |
3889 | 3889 |
3890 // Check that the code was patched as expected. | 3890 // Check that the code was patched as expected. |
3891 ASSERT(masm_.pc_ == address_ + size_); | 3891 ASSERT(masm_.pc_ == address_ + size_); |
3892 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3892 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
3893 } | 3893 } |
3894 | 3894 |
3895 } } // namespace v8::internal | 3895 } } // namespace v8::internal |
3896 | 3896 |
3897 #endif // V8_TARGET_ARCH_X64 | 3897 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |