Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 8540005: Revert "Add a level of indirection to exception handler addresses." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2399 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 movq(dst, SafepointRegisterSlot(src)); 2410 movq(dst, SafepointRegisterSlot(src));
2411 } 2411 }
2412 2412
2413 2413
2414 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { 2414 Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
2415 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 2415 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
2416 } 2416 }
2417 2417
2418 2418
2419 void MacroAssembler::PushTryHandler(CodeLocation try_location, 2419 void MacroAssembler::PushTryHandler(CodeLocation try_location,
2420 HandlerType type, 2420 HandlerType type) {
2421 int handler_index) {
2422 // Adjust this code if not the case. 2421 // Adjust this code if not the case.
2423 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 2422 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2424 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2423 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2425 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 2424 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2426 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 2425 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2427 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 2426 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2428 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 2427 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2429 2428
2430 // We will build up the handler from the bottom by pushing on the stack. 2429 // The pc (return address) is already on TOS. This code pushes state,
2431 // First compute the state and push the frame pointer and context. 2430 // frame pointer, context, and current handler.
2432 unsigned state = StackHandler::OffsetField::encode(handler_index);
2433 if (try_location == IN_JAVASCRIPT) { 2431 if (try_location == IN_JAVASCRIPT) {
2432 if (type == TRY_CATCH_HANDLER) {
2433 push(Immediate(StackHandler::TRY_CATCH));
2434 } else {
2435 push(Immediate(StackHandler::TRY_FINALLY));
2436 }
2434 push(rbp); 2437 push(rbp);
2435 push(rsi); 2438 push(rsi);
2436 state |= (type == TRY_CATCH_HANDLER)
2437 ? StackHandler::KindField::encode(StackHandler::TRY_CATCH)
2438 : StackHandler::KindField::encode(StackHandler::TRY_FINALLY);
2439 } else { 2439 } else {
2440 ASSERT(try_location == IN_JS_ENTRY); 2440 ASSERT(try_location == IN_JS_ENTRY);
2441 // The frame pointer does not point to a JS frame so we save NULL for 2441 // The frame pointer does not point to a JS frame so we save NULL
2442 // rbp. We expect the code throwing an exception to check rbp before 2442 // for rbp. We expect the code throwing an exception to check rbp
2443 // dereferencing it to restore the context. 2443 // before dereferencing it to restore the context.
2444 push(Immediate(StackHandler::ENTRY));
2444 push(Immediate(0)); // NULL frame pointer. 2445 push(Immediate(0)); // NULL frame pointer.
2445 Push(Smi::FromInt(0)); // No context. 2446 Push(Smi::FromInt(0)); // No context.
2446 state |= StackHandler::KindField::encode(StackHandler::ENTRY);
2447 } 2447 }
2448 2448 // Save the current handler.
2449 // Push the state and the code object. 2449 Operand handler_operand =
2450 push(Immediate(state)); 2450 ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate()));
2451 Push(CodeObject()); 2451 push(handler_operand);
2452 2452 // Link this handler.
2453 // Link the current handler as the next handler. 2453 movq(handler_operand, rsp);
2454 ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
2455 push(ExternalOperand(handler_address));
2456 // Set this new handler as the current one.
2457 movq(ExternalOperand(handler_address), rsp);
2458 } 2454 }
2459 2455
2460 2456
2461 void MacroAssembler::PopTryHandler() { 2457 void MacroAssembler::PopTryHandler() {
2462 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2458 ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
2463 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 2459 // Unlink this handler.
2464 pop(ExternalOperand(handler_address)); 2460 Operand handler_operand =
2461 ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate()));
2462 pop(handler_operand);
2463 // Remove the remaining fields.
2465 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 2464 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
2466 } 2465 }
2467 2466
2468 2467
2469 void MacroAssembler::JumpToHandlerEntry() {
2470 // Compute the handler entry address and jump to it. The handler table is
2471 // a fixed array of (smi-tagged) code offsets.
2472 // rax = exception, rdi = code object, rdx = state.
2473 movq(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
2474 shr(rdx, Immediate(StackHandler::kKindWidth));
2475 movq(rdx, FieldOperand(rbx, rdx, times_8, FixedArray::kHeaderSize));
2476 SmiToInteger64(rdx, rdx);
2477 lea(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize));
2478 jmp(rdi);
2479 }
2480
2481
2482 void MacroAssembler::Throw(Register value) { 2468 void MacroAssembler::Throw(Register value) {
2483 // Adjust this code if not the case. 2469 // Adjust this code if not the case.
2484 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 2470 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2485 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2471 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2486 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 2472 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2487 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 2473 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2488 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 2474 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2489 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 2475 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2490 2476 // Keep thrown value in rax.
2491 // The exception is expected in rax.
2492 if (!value.is(rax)) { 2477 if (!value.is(rax)) {
2493 movq(rax, value); 2478 movq(rax, value);
2494 } 2479 }
2495 // Drop the stack pointer to the top of the top handler. 2480
2496 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 2481 ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
2497 movq(rsp, ExternalOperand(handler_address)); 2482 Operand handler_operand = ExternalOperand(handler_address);
2498 // Restore the next handler. 2483 movq(rsp, handler_operand);
2499 pop(ExternalOperand(handler_address)); 2484 // get next in chain
2500 2485 pop(handler_operand);
2501 // Remove the code object and state, compute the handler address in rdi.
2502 pop(rdi); // Code object.
2503 pop(rdx); // Offset and state.
2504
2505 // Restore the context and frame pointer.
2506 pop(rsi); // Context. 2486 pop(rsi); // Context.
2507 pop(rbp); // Frame pointer. 2487 pop(rbp); // Frame pointer.
2488 pop(rdx); // State.
2508 2489
2509 // If the handler is a JS frame, restore the context to the frame. 2490 // If the handler is a JS frame, restore the context to the frame.
2510 // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either 2491 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any
2511 // rbp or rsi. 2492 // of them.
2512 Label skip; 2493 Label skip;
2513 testq(rsi, rsi); 2494 cmpq(rdx, Immediate(StackHandler::ENTRY));
2514 j(zero, &skip, Label::kNear); 2495 j(equal, &skip, Label::kNear);
2515 movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 2496 movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
2516 bind(&skip); 2497 bind(&skip);
2517 2498
2518 JumpToHandlerEntry(); 2499 ret(0);
2519 } 2500 }
2520 2501
2521 2502
2522 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, 2503 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
2523 Register value) { 2504 Register value) {
2524 // Adjust this code if not the case. 2505 // Adjust this code if not the case.
2525 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 2506 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2526 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2507 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2527 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 2508 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2528 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 2509 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2529 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 2510 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2530 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 2511 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2531 2512
2532 // The exception is expected in rax. 2513 // The exception is expected in rax.
2533 if (type == OUT_OF_MEMORY) { 2514 if (type == OUT_OF_MEMORY) {
2534 // Set external caught exception to false. 2515 // Set external caught exception to false.
2535 ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, 2516 ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
2536 isolate()); 2517 isolate());
2537 Set(rax, static_cast<int64_t>(false)); 2518 Set(rax, static_cast<int64_t>(false));
2538 Store(external_caught, rax); 2519 Store(external_caught, rax);
2539 2520
2540 // Set pending exception and rax to out of memory exception. 2521 // Set pending exception and rax to out of memory exception.
2541 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 2522 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
2542 isolate()); 2523 isolate());
2543 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); 2524 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
2544 Store(pending_exception, rax); 2525 Store(pending_exception, rax);
2545 } else if (!value.is(rax)) { 2526 } else if (!value.is(rax)) {
2546 movq(rax, value); 2527 movq(rax, value);
2547 } 2528 }
2548 2529
2549 // Drop the stack pointer to the top of the top stack handler. 2530 // Drop the stack pointer to the top of the top stack handler.
2550 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 2531 ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
2551 Load(rsp, handler_address); 2532 Load(rsp, handler_address);
2552 2533
2553 // Unwind the handlers until the top ENTRY handler is found. 2534 // Unwind the handlers until the top ENTRY handler is found.
2554 Label fetch_next, check_kind; 2535 Label fetch_next, check_kind;
2555 jmp(&check_kind, Label::kNear); 2536 jmp(&check_kind, Label::kNear);
2556 bind(&fetch_next); 2537 bind(&fetch_next);
2557 movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset)); 2538 movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset));
2558 2539
2559 bind(&check_kind); 2540 bind(&check_kind);
2560 STATIC_ASSERT(StackHandler::ENTRY == 0); 2541 cmpq(Operand(rsp, StackHandlerConstants::kStateOffset),
2561 testl(Operand(rsp, StackHandlerConstants::kStateOffset), 2542 Immediate(StackHandler::ENTRY));
2562 Immediate(StackHandler::KindField::kMask)); 2543 j(not_equal, &fetch_next);
2563 j(not_zero, &fetch_next);
2564 2544
2565 // Set the top handler address to next handler past the top ENTRY handler. 2545 // Set the top handler address to next handler past the top ENTRY handler.
2566 pop(ExternalOperand(handler_address)); 2546 pop(ExternalOperand(handler_address));
2567 2547
2568 // Remove the code object and state, compute the handler address in rdi. 2548 // Clear the context and frame pointer (0 was saved in the handler), and
2569 pop(rdi); // Code object. 2549 // discard the state.
2570 pop(rdx); // Offset and state.
2571
2572 // Clear the context pointer and frame pointer (0 was saved in the handler).
2573 pop(rsi); 2550 pop(rsi);
2574 pop(rbp); 2551 pop(rbp);
2552 pop(rdx); // State.
2575 2553
2576 JumpToHandlerEntry(); 2554 ret(0);
2577 } 2555 }
2578 2556
2579 2557
2580 void MacroAssembler::Ret() { 2558 void MacroAssembler::Ret() {
2581 ret(0); 2559 ret(0);
2582 } 2560 }
2583 2561
2584 2562
2585 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2563 void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
2586 if (is_uint16(bytes_dropped)) { 2564 if (is_uint16(bytes_dropped)) {
(...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after
4242 4220
4243 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4221 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
4244 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4222 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
4245 4223
4246 bind(&done); 4224 bind(&done);
4247 } 4225 }
4248 4226
4249 } } // namespace v8::internal 4227 } } // namespace v8::internal
4250 4228
4251 #endif // V8_TARGET_ARCH_X64 4229 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698