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 2369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2380 | 2380 |
2381 | 2381 |
2382 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { | 2382 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { |
2383 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); | 2383 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); |
2384 } | 2384 } |
2385 | 2385 |
2386 | 2386 |
2387 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 2387 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
2388 HandlerType type) { | 2388 HandlerType type) { |
2389 // Adjust this code if not the case. | 2389 // Adjust this code if not the case. |
2390 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 2390 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2391 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2392 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 2393 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 2394 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 2395 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
2391 | 2396 |
2392 // The pc (return address) is already on TOS. This code pushes state, | 2397 // The pc (return address) is already on TOS. This code pushes state, |
2393 // frame pointer and current handler. Check that they are expected | 2398 // frame pointer, context, and current handler. |
2394 // next on the stack, in that order. | |
2395 ASSERT_EQ(StackHandlerConstants::kStateOffset, | |
2396 StackHandlerConstants::kPCOffset - kPointerSize); | |
2397 ASSERT_EQ(StackHandlerConstants::kFPOffset, | |
2398 StackHandlerConstants::kStateOffset - kPointerSize); | |
2399 ASSERT_EQ(StackHandlerConstants::kNextOffset, | |
2400 StackHandlerConstants::kFPOffset - kPointerSize); | |
2401 | |
2402 if (try_location == IN_JAVASCRIPT) { | 2399 if (try_location == IN_JAVASCRIPT) { |
2403 if (type == TRY_CATCH_HANDLER) { | 2400 if (type == TRY_CATCH_HANDLER) { |
2404 push(Immediate(StackHandler::TRY_CATCH)); | 2401 push(Immediate(StackHandler::TRY_CATCH)); |
2405 } else { | 2402 } else { |
2406 push(Immediate(StackHandler::TRY_FINALLY)); | 2403 push(Immediate(StackHandler::TRY_FINALLY)); |
2407 } | 2404 } |
2408 push(rbp); | 2405 push(rbp); |
| 2406 push(rsi); |
2409 } else { | 2407 } else { |
2410 ASSERT(try_location == IN_JS_ENTRY); | 2408 ASSERT(try_location == IN_JS_ENTRY); |
2411 // 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 |
2412 // 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 |
2413 // before dereferencing it to restore the context. | 2411 // before dereferencing it to restore the context. |
2414 push(Immediate(StackHandler::ENTRY)); | 2412 push(Immediate(StackHandler::ENTRY)); |
2415 push(Immediate(0)); // NULL frame pointer. | 2413 push(Immediate(0)); // NULL frame pointer. |
| 2414 Push(Smi::FromInt(0)); // No context. |
2416 } | 2415 } |
2417 // Save the current handler. | 2416 // Save the current handler. |
2418 Operand handler_operand = | 2417 Operand handler_operand = |
2419 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2418 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); |
2420 push(handler_operand); | 2419 push(handler_operand); |
2421 // Link this handler. | 2420 // Link this handler. |
2422 movq(handler_operand, rsp); | 2421 movq(handler_operand, rsp); |
2423 } | 2422 } |
2424 | 2423 |
2425 | 2424 |
2426 void MacroAssembler::PopTryHandler() { | 2425 void MacroAssembler::PopTryHandler() { |
2427 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 2426 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
2428 // Unlink this handler. | 2427 // Unlink this handler. |
2429 Operand handler_operand = | 2428 Operand handler_operand = |
2430 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); | 2429 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); |
2431 pop(handler_operand); | 2430 pop(handler_operand); |
2432 // Remove the remaining fields. | 2431 // Remove the remaining fields. |
2433 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 2432 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
2434 } | 2433 } |
2435 | 2434 |
2436 | 2435 |
2437 void MacroAssembler::Throw(Register value) { | 2436 void MacroAssembler::Throw(Register value) { |
2438 // Check that stack should contain next handler, frame pointer, state and | 2437 // Adjust this code if not the case. |
2439 // return address in that order. | 2438 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
2440 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == | 2439 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
2441 StackHandlerConstants::kStateOffset); | 2440 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == | 2441 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
2443 StackHandlerConstants::kPCOffset); | 2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * 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::k_handler_address, 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(rbp); // pop frame pointer | 2454 pop(rsi); // Context. |
2455 pop(rdx); // remove state | 2455 pop(rbp); // Frame pointer. |
| 2456 pop(rdx); // State. |
2456 | 2457 |
2457 // Before returning we restore the context from the frame pointer if not NULL. | 2458 // If the handler is a JS frame, restore the context to the frame. |
2458 // The frame pointer is NULL in the exception handler of a JS entry frame. | 2459 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any |
2459 Set(rsi, 0); // Tentatively set context pointer to NULL | 2460 // of them. |
2460 Label skip; | 2461 Label skip; |
2461 cmpq(rbp, Immediate(0)); | 2462 cmpq(rdx, Immediate(StackHandler::ENTRY)); |
2462 j(equal, &skip, Label::kNear); | 2463 j(equal, &skip, Label::kNear); |
2463 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2464 movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); |
2464 bind(&skip); | 2465 bind(&skip); |
| 2466 |
2465 ret(0); | 2467 ret(0); |
2466 } | 2468 } |
2467 | 2469 |
2468 | 2470 |
2469 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 2471 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
2470 Register value) { | 2472 Register value) { |
| 2473 // Adjust this code if not the case. |
| 2474 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2475 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2476 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 2477 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 2478 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 2479 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
2471 // Keep thrown value in rax. | 2480 // Keep thrown value in rax. |
2472 if (!value.is(rax)) { | 2481 if (!value.is(rax)) { |
2473 movq(rax, value); | 2482 movq(rax, value); |
2474 } | 2483 } |
2475 // Fetch top stack handler. | 2484 // Fetch top stack handler. |
2476 ExternalReference handler_address(Isolate::k_handler_address, isolate()); | 2485 ExternalReference handler_address(Isolate::k_handler_address, isolate()); |
2477 Load(rsp, handler_address); | 2486 Load(rsp, handler_address); |
2478 | 2487 |
2479 // Unwind the handlers until the ENTRY handler is found. | 2488 // Unwind the handlers until the ENTRY handler is found. |
2480 Label loop, done; | 2489 Label loop, done; |
(...skipping 19 matching lines...) Expand all Loading... |
2500 Set(rax, static_cast<int64_t>(false)); | 2509 Set(rax, static_cast<int64_t>(false)); |
2501 Store(external_caught, rax); | 2510 Store(external_caught, rax); |
2502 | 2511 |
2503 // Set pending exception and rax to out of memory exception. | 2512 // Set pending exception and rax to out of memory exception. |
2504 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 2513 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
2505 isolate()); | 2514 isolate()); |
2506 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); | 2515 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); |
2507 Store(pending_exception, rax); | 2516 Store(pending_exception, rax); |
2508 } | 2517 } |
2509 | 2518 |
2510 // Clear the context pointer. | 2519 // Discard the context saved in the handler and clear the context pointer. |
| 2520 pop(rdx); |
2511 Set(rsi, 0); | 2521 Set(rsi, 0); |
2512 | 2522 |
2513 // Restore registers from handler. | 2523 pop(rbp); // Restore frame pointer. |
2514 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == | 2524 pop(rdx); // Discard state. |
2515 StackHandlerConstants::kFPOffset); | |
2516 pop(rbp); // FP | |
2517 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == | |
2518 StackHandlerConstants::kStateOffset); | |
2519 pop(rdx); // State | |
2520 | 2525 |
2521 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == | |
2522 StackHandlerConstants::kPCOffset); | |
2523 ret(0); | 2526 ret(0); |
2524 } | 2527 } |
2525 | 2528 |
2526 | 2529 |
2527 void MacroAssembler::Ret() { | 2530 void MacroAssembler::Ret() { |
2528 ret(0); | 2531 ret(0); |
2529 } | 2532 } |
2530 | 2533 |
2531 | 2534 |
2532 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { | 2535 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { |
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3849 CPU::FlushICache(address_, size_); | 3852 CPU::FlushICache(address_, size_); |
3850 | 3853 |
3851 // Check that the code was patched as expected. | 3854 // Check that the code was patched as expected. |
3852 ASSERT(masm_.pc_ == address_ + size_); | 3855 ASSERT(masm_.pc_ == address_ + size_); |
3853 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3856 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
3854 } | 3857 } |
3855 | 3858 |
3856 } } // namespace v8::internal | 3859 } } // namespace v8::internal |
3857 | 3860 |
3858 #endif // V8_TARGET_ARCH_X64 | 3861 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |