| 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 2439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2450 | 2450 |
| 2451 | 2451 |
| 2452 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { | 2452 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { |
| 2453 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); | 2453 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); |
| 2454 } | 2454 } |
| 2455 | 2455 |
| 2456 | 2456 |
| 2457 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 2457 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 2458 HandlerType type) { | 2458 HandlerType type) { |
| 2459 // Adjust this code if not the case. | 2459 // Adjust this code if not the case. |
| 2460 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 2460 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2461 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2462 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 2463 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 2464 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 2465 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2461 | 2466 |
| 2462 // The pc (return address) is already on TOS. This code pushes state, | 2467 // The pc (return address) is already on TOS. This code pushes state, |
| 2463 // frame pointer and current handler. Check that they are expected | 2468 // frame pointer, context, and current handler. |
| 2464 // next on the stack, in that order. | |
| 2465 ASSERT_EQ(StackHandlerConstants::kStateOffset, | |
| 2466 StackHandlerConstants::kPCOffset - kPointerSize); | |
| 2467 ASSERT_EQ(StackHandlerConstants::kFPOffset, | |
| 2468 StackHandlerConstants::kStateOffset - kPointerSize); | |
| 2469 ASSERT_EQ(StackHandlerConstants::kNextOffset, | |
| 2470 StackHandlerConstants::kFPOffset - kPointerSize); | |
| 2471 | |
| 2472 if (try_location == IN_JAVASCRIPT) { | 2469 if (try_location == IN_JAVASCRIPT) { |
| 2473 if (type == TRY_CATCH_HANDLER) { | 2470 if (type == TRY_CATCH_HANDLER) { |
| 2474 push(Immediate(StackHandler::TRY_CATCH)); | 2471 push(Immediate(StackHandler::TRY_CATCH)); |
| 2475 } else { | 2472 } else { |
| 2476 push(Immediate(StackHandler::TRY_FINALLY)); | 2473 push(Immediate(StackHandler::TRY_FINALLY)); |
| 2477 } | 2474 } |
| 2478 push(rbp); | 2475 push(rbp); |
| 2476 push(rsi); |
| 2479 } else { | 2477 } else { |
| 2480 ASSERT(try_location == IN_JS_ENTRY); | 2478 ASSERT(try_location == IN_JS_ENTRY); |
| 2481 // The frame pointer does not point to a JS frame so we save NULL | 2479 // The frame pointer does not point to a JS frame so we save NULL |
| 2482 // for rbp. We expect the code throwing an exception to check rbp | 2480 // for rbp. We expect the code throwing an exception to check rbp |
| 2483 // before dereferencing it to restore the context. | 2481 // before dereferencing it to restore the context. |
| 2484 push(Immediate(StackHandler::ENTRY)); | 2482 push(Immediate(StackHandler::ENTRY)); |
| 2485 push(Immediate(0)); // NULL frame pointer. | 2483 push(Immediate(0)); // NULL frame pointer. |
| 2484 Push(Smi::FromInt(0)); // No context. |
| 2486 } | 2485 } |
| 2487 // Save the current handler. | 2486 // Save the current handler. |
| 2488 Operand handler_operand = | 2487 Operand handler_operand = |
| 2489 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2488 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); |
| 2490 push(handler_operand); | 2489 push(handler_operand); |
| 2491 // Link this handler. | 2490 // Link this handler. |
| 2492 movq(handler_operand, rsp); | 2491 movq(handler_operand, rsp); |
| 2493 } | 2492 } |
| 2494 | 2493 |
| 2495 | 2494 |
| 2496 void MacroAssembler::PopTryHandler() { | 2495 void MacroAssembler::PopTryHandler() { |
| 2497 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 2496 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
| 2498 // Unlink this handler. | 2497 // Unlink this handler. |
| 2499 Operand handler_operand = | 2498 Operand handler_operand = |
| 2500 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2499 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); |
| 2501 pop(handler_operand); | 2500 pop(handler_operand); |
| 2502 // Remove the remaining fields. | 2501 // Remove the remaining fields. |
| 2503 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 2502 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
| 2504 } | 2503 } |
| 2505 | 2504 |
| 2506 | 2505 |
| 2507 void MacroAssembler::Throw(Register value) { | 2506 void MacroAssembler::Throw(Register value) { |
| 2508 // Check that stack should contain next handler, frame pointer, state and | 2507 // Adjust this code if not the case. |
| 2509 // return address in that order. | 2508 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2510 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == | 2509 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2511 StackHandlerConstants::kStateOffset); | 2510 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 2512 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == | 2511 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 2513 StackHandlerConstants::kPCOffset); | 2512 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 2513 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2514 // Keep thrown value in rax. | 2514 // Keep thrown value in rax. |
| 2515 if (!value.is(rax)) { | 2515 if (!value.is(rax)) { |
| 2516 movq(rax, value); | 2516 movq(rax, value); |
| 2517 } | 2517 } |
| 2518 | 2518 |
| 2519 ExternalReference handler_address(Isolate::k_handler_address, isolate()); | 2519 ExternalReference handler_address(Isolate::k_handler_address, isolate()); |
| 2520 Operand handler_operand = ExternalOperand(handler_address); | 2520 Operand handler_operand = ExternalOperand(handler_address); |
| 2521 movq(rsp, handler_operand); | 2521 movq(rsp, handler_operand); |
| 2522 // get next in chain | 2522 // get next in chain |
| 2523 pop(handler_operand); | 2523 pop(handler_operand); |
| 2524 pop(rbp); // pop frame pointer | 2524 pop(rsi); // Context. |
| 2525 pop(rdx); // remove state | 2525 pop(rbp); // Frame pointer. |
| 2526 pop(rdx); // State. |
| 2526 | 2527 |
| 2527 // Before returning we restore the context from the frame pointer if not NULL. | 2528 // If the handler is a JS frame, restore the context to the frame. |
| 2528 // The frame pointer is NULL in the exception handler of a JS entry frame. | 2529 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any |
| 2529 Set(rsi, 0); // Tentatively set context pointer to NULL | 2530 // of them. |
| 2530 Label skip; | 2531 Label skip; |
| 2531 cmpq(rbp, Immediate(0)); | 2532 cmpq(rdx, Immediate(StackHandler::ENTRY)); |
| 2532 j(equal, &skip, Label::kNear); | 2533 j(equal, &skip, Label::kNear); |
| 2533 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2534 movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); |
| 2534 bind(&skip); | 2535 bind(&skip); |
| 2536 |
| 2535 ret(0); | 2537 ret(0); |
| 2536 } | 2538 } |
| 2537 | 2539 |
| 2538 | 2540 |
| 2539 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 2541 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
| 2540 Register value) { | 2542 Register value) { |
| 2543 // Adjust this code if not the case. |
| 2544 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2545 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2546 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 2547 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 2548 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 2549 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2541 // Keep thrown value in rax. | 2550 // Keep thrown value in rax. |
| 2542 if (!value.is(rax)) { | 2551 if (!value.is(rax)) { |
| 2543 movq(rax, value); | 2552 movq(rax, value); |
| 2544 } | 2553 } |
| 2545 // Fetch top stack handler. | 2554 // Fetch top stack handler. |
| 2546 ExternalReference handler_address(Isolate::k_handler_address, isolate()); | 2555 ExternalReference handler_address(Isolate::k_handler_address, isolate()); |
| 2547 Load(rsp, handler_address); | 2556 Load(rsp, handler_address); |
| 2548 | 2557 |
| 2549 // Unwind the handlers until the ENTRY handler is found. | 2558 // Unwind the handlers until the ENTRY handler is found. |
| 2550 Label loop, done; | 2559 Label loop, done; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2570 Set(rax, static_cast<int64_t>(false)); | 2579 Set(rax, static_cast<int64_t>(false)); |
| 2571 Store(external_caught, rax); | 2580 Store(external_caught, rax); |
| 2572 | 2581 |
| 2573 // Set pending exception and rax to out of memory exception. | 2582 // Set pending exception and rax to out of memory exception. |
| 2574 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 2583 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 2575 isolate()); | 2584 isolate()); |
| 2576 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); | 2585 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); |
| 2577 Store(pending_exception, rax); | 2586 Store(pending_exception, rax); |
| 2578 } | 2587 } |
| 2579 | 2588 |
| 2580 // Clear the context pointer. | 2589 // Discard the context saved in the handler and clear the context pointer. |
| 2590 pop(rdx); |
| 2581 Set(rsi, 0); | 2591 Set(rsi, 0); |
| 2582 | 2592 |
| 2583 // Restore registers from handler. | 2593 pop(rbp); // Restore frame pointer. |
| 2584 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == | 2594 pop(rdx); // Discard state. |
| 2585 StackHandlerConstants::kFPOffset); | |
| 2586 pop(rbp); // FP | |
| 2587 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == | |
| 2588 StackHandlerConstants::kStateOffset); | |
| 2589 pop(rdx); // State | |
| 2590 | 2595 |
| 2591 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == | |
| 2592 StackHandlerConstants::kPCOffset); | |
| 2593 ret(0); | 2596 ret(0); |
| 2594 } | 2597 } |
| 2595 | 2598 |
| 2596 | 2599 |
| 2597 void MacroAssembler::Ret() { | 2600 void MacroAssembler::Ret() { |
| 2598 ret(0); | 2601 ret(0); |
| 2599 } | 2602 } |
| 2600 | 2603 |
| 2601 | 2604 |
| 2602 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { | 2605 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4119 | 4122 |
| 4120 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); | 4123 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); |
| 4121 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); | 4124 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); |
| 4122 | 4125 |
| 4123 bind(&done); | 4126 bind(&done); |
| 4124 } | 4127 } |
| 4125 | 4128 |
| 4126 } } // namespace v8::internal | 4129 } } // namespace v8::internal |
| 4127 | 4130 |
| 4128 #endif // V8_TARGET_ARCH_X64 | 4131 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |