OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 // Return and remove the on-stack parameters. | 1036 // Return and remove the on-stack parameters. |
1037 __ bind(&done); | 1037 __ bind(&done); |
1038 __ ret(3 * kPointerSize); | 1038 __ ret(3 * kPointerSize); |
1039 | 1039 |
1040 // Do the runtime call to allocate the arguments object. | 1040 // Do the runtime call to allocate the arguments object. |
1041 __ bind(&runtime); | 1041 __ bind(&runtime); |
1042 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 1042 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1043 } | 1043 } |
1044 | 1044 |
1045 | 1045 |
| 1046 static void ThrowPendingException(MacroAssembler* masm) { |
| 1047 Isolate* isolate = masm->isolate(); |
| 1048 |
| 1049 ExternalReference pending_handler_context_address( |
| 1050 Isolate::kPendingHandlerContextAddress, isolate); |
| 1051 ExternalReference pending_handler_code_address( |
| 1052 Isolate::kPendingHandlerCodeAddress, isolate); |
| 1053 ExternalReference pending_handler_offset_address( |
| 1054 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 1055 ExternalReference pending_handler_fp_address( |
| 1056 Isolate::kPendingHandlerFPAddress, isolate); |
| 1057 ExternalReference pending_handler_sp_address( |
| 1058 Isolate::kPendingHandlerSPAddress, isolate); |
| 1059 |
| 1060 // Ask the runtime for help to determine the handler. This will set rax to |
| 1061 // contain the current pending exception, don't clobber it. |
| 1062 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 1063 { |
| 1064 FrameScope scope(masm, StackFrame::MANUAL); |
| 1065 __ movp(arg_reg_1, Immediate(0)); // argc. |
| 1066 __ movp(arg_reg_2, Immediate(0)); // argv. |
| 1067 __ Move(arg_reg_3, ExternalReference::isolate_address(isolate)); |
| 1068 __ PrepareCallCFunction(3); |
| 1069 __ CallCFunction(find_handler, 3); |
| 1070 } |
| 1071 |
| 1072 // Retrieve the handler context, SP and FP. |
| 1073 __ movp(rsi, masm->ExternalOperand(pending_handler_context_address)); |
| 1074 __ movp(rsp, masm->ExternalOperand(pending_handler_sp_address)); |
| 1075 __ movp(rbp, masm->ExternalOperand(pending_handler_fp_address)); |
| 1076 |
| 1077 // If the handler is a JS frame, restore the context to the frame. |
| 1078 // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either |
| 1079 // rbp or rsi. |
| 1080 Label skip; |
| 1081 __ testp(rsi, rsi); |
| 1082 __ j(zero, &skip, Label::kNear); |
| 1083 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); |
| 1084 __ bind(&skip); |
| 1085 |
| 1086 // Compute the handler entry address and jump to it. |
| 1087 __ movp(rdi, masm->ExternalOperand(pending_handler_code_address)); |
| 1088 __ movp(rdx, masm->ExternalOperand(pending_handler_offset_address)); |
| 1089 __ leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize)); |
| 1090 __ jmp(rdi); |
| 1091 } |
| 1092 |
| 1093 |
1046 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1094 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1047 // Just jump directly to runtime if native RegExp is not selected at compile | 1095 // Just jump directly to runtime if native RegExp is not selected at compile |
1048 // time or if regexp entry in generated code is turned off runtime switch or | 1096 // time or if regexp entry in generated code is turned off runtime switch or |
1049 // at compilation. | 1097 // at compilation. |
1050 #ifdef V8_INTERPRETED_REGEXP | 1098 #ifdef V8_INTERPRETED_REGEXP |
1051 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 1099 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1052 #else // V8_INTERPRETED_REGEXP | 1100 #else // V8_INTERPRETED_REGEXP |
1053 | 1101 |
1054 // Stack frame on entry. | 1102 // Stack frame on entry. |
1055 // rsp[0] : return address | 1103 // rsp[0] : return address |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 // haven't created the exception yet. Handle that in the runtime system. | 1470 // haven't created the exception yet. Handle that in the runtime system. |
1423 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 1471 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
1424 ExternalReference pending_exception_address( | 1472 ExternalReference pending_exception_address( |
1425 Isolate::kPendingExceptionAddress, isolate()); | 1473 Isolate::kPendingExceptionAddress, isolate()); |
1426 Operand pending_exception_operand = | 1474 Operand pending_exception_operand = |
1427 masm->ExternalOperand(pending_exception_address, rbx); | 1475 masm->ExternalOperand(pending_exception_address, rbx); |
1428 __ movp(rax, pending_exception_operand); | 1476 __ movp(rax, pending_exception_operand); |
1429 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); | 1477 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); |
1430 __ cmpp(rax, rdx); | 1478 __ cmpp(rax, rdx); |
1431 __ j(equal, &runtime); | 1479 __ j(equal, &runtime); |
1432 __ movp(pending_exception_operand, rdx); | |
1433 | 1480 |
1434 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); | 1481 // For exception, throw the exception again. |
1435 Label termination_exception; | 1482 __ EnterExitFrame(false); |
1436 __ j(equal, &termination_exception, Label::kNear); | 1483 ThrowPendingException(masm); |
1437 __ Throw(rax); | |
1438 | |
1439 __ bind(&termination_exception); | |
1440 __ ThrowUncatchable(rax); | |
1441 | 1484 |
1442 // Do the runtime call to execute the regexp. | 1485 // Do the runtime call to execute the regexp. |
1443 __ bind(&runtime); | 1486 __ bind(&runtime); |
1444 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 1487 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1445 | 1488 |
1446 // Deferred code for string handling. | 1489 // Deferred code for string handling. |
1447 // (7) Not a long external string? If yes, go to (10). | 1490 // (7) Not a long external string? If yes, go to (10). |
1448 __ bind(¬_seq_nor_cons); | 1491 __ bind(¬_seq_nor_cons); |
1449 // Compare flags are still set from (3). | 1492 // Compare flags are still set from (3). |
1450 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). | 1493 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2419 __ j(not_equal, &okay, Label::kNear); | 2462 __ j(not_equal, &okay, Label::kNear); |
2420 __ int3(); | 2463 __ int3(); |
2421 __ bind(&okay); | 2464 __ bind(&okay); |
2422 } | 2465 } |
2423 | 2466 |
2424 // Check result for exception sentinel. | 2467 // Check result for exception sentinel. |
2425 Label exception_returned; | 2468 Label exception_returned; |
2426 __ CompareRoot(rax, Heap::kExceptionRootIndex); | 2469 __ CompareRoot(rax, Heap::kExceptionRootIndex); |
2427 __ j(equal, &exception_returned); | 2470 __ j(equal, &exception_returned); |
2428 | 2471 |
2429 ExternalReference pending_exception_address( | |
2430 Isolate::kPendingExceptionAddress, isolate()); | |
2431 | |
2432 // Check that there is no pending exception, otherwise we | 2472 // Check that there is no pending exception, otherwise we |
2433 // should have returned the exception sentinel. | 2473 // should have returned the exception sentinel. |
2434 if (FLAG_debug_code) { | 2474 if (FLAG_debug_code) { |
2435 Label okay; | 2475 Label okay; |
2436 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); | 2476 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
| 2477 ExternalReference pending_exception_address( |
| 2478 Isolate::kPendingExceptionAddress, isolate()); |
2437 Operand pending_exception_operand = | 2479 Operand pending_exception_operand = |
2438 masm->ExternalOperand(pending_exception_address); | 2480 masm->ExternalOperand(pending_exception_address); |
2439 __ cmpp(r14, pending_exception_operand); | 2481 __ cmpp(r14, pending_exception_operand); |
2440 __ j(equal, &okay, Label::kNear); | 2482 __ j(equal, &okay, Label::kNear); |
2441 __ int3(); | 2483 __ int3(); |
2442 __ bind(&okay); | 2484 __ bind(&okay); |
2443 } | 2485 } |
2444 | 2486 |
2445 // Exit the JavaScript to C++ exit frame. | 2487 // Exit the JavaScript to C++ exit frame. |
2446 __ LeaveExitFrame(save_doubles()); | 2488 __ LeaveExitFrame(save_doubles()); |
2447 __ ret(0); | 2489 __ ret(0); |
2448 | 2490 |
2449 // Handling of exception. | 2491 // Handling of exception. |
2450 __ bind(&exception_returned); | 2492 __ bind(&exception_returned); |
2451 | 2493 ThrowPendingException(masm); |
2452 // Retrieve the pending exception. | |
2453 Operand pending_exception_operand = | |
2454 masm->ExternalOperand(pending_exception_address); | |
2455 __ movp(rax, pending_exception_operand); | |
2456 | |
2457 // Clear the pending exception. | |
2458 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); | |
2459 __ movp(pending_exception_operand, rdx); | |
2460 | |
2461 // Special handling of termination exceptions which are uncatchable | |
2462 // by javascript code. | |
2463 Label throw_termination_exception; | |
2464 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); | |
2465 __ j(equal, &throw_termination_exception); | |
2466 | |
2467 // Handle normal exception. | |
2468 __ Throw(rax); | |
2469 | |
2470 __ bind(&throw_termination_exception); | |
2471 __ ThrowUncatchable(rax); | |
2472 } | 2494 } |
2473 | 2495 |
2474 | 2496 |
2475 void JSEntryStub::Generate(MacroAssembler* masm) { | 2497 void JSEntryStub::Generate(MacroAssembler* masm) { |
2476 Label invoke, handler_entry, exit; | 2498 Label invoke, handler_entry, exit; |
2477 Label not_outermost_js, not_outermost_js_2; | 2499 Label not_outermost_js, not_outermost_js_2; |
2478 | 2500 |
2479 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2501 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2480 | 2502 |
2481 { // NOLINT. Scope block confuses linter. | 2503 { // NOLINT. Scope block confuses linter. |
(...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5095 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, | 5117 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, |
5096 kStackSpace, nullptr, return_value_operand, NULL); | 5118 kStackSpace, nullptr, return_value_operand, NULL); |
5097 } | 5119 } |
5098 | 5120 |
5099 | 5121 |
5100 #undef __ | 5122 #undef __ |
5101 | 5123 |
5102 } } // namespace v8::internal | 5124 } } // namespace v8::internal |
5103 | 5125 |
5104 #endif // V8_TARGET_ARCH_X64 | 5126 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |