| 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 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2330 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); | 2330 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2331 | 2331 |
| 2332 // The return address is passed in register ra. | 2332 // The return address is passed in register ra. |
| 2333 if (try_location == IN_JAVASCRIPT) { | 2333 if (try_location == IN_JAVASCRIPT) { |
| 2334 if (type == TRY_CATCH_HANDLER) { | 2334 if (type == TRY_CATCH_HANDLER) { |
| 2335 li(t0, Operand(StackHandler::TRY_CATCH)); | 2335 li(t0, Operand(StackHandler::TRY_CATCH)); |
| 2336 } else { | 2336 } else { |
| 2337 li(t0, Operand(StackHandler::TRY_FINALLY)); | 2337 li(t0, Operand(StackHandler::TRY_FINALLY)); |
| 2338 } | 2338 } |
| 2339 // Save the current handler as the next handler. | 2339 // Save the current handler as the next handler. |
| 2340 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 2340 li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| 2341 lw(t1, MemOperand(t2)); | 2341 lw(t1, MemOperand(t2)); |
| 2342 | 2342 |
| 2343 addiu(sp, sp, -StackHandlerConstants::kSize); | 2343 addiu(sp, sp, -StackHandlerConstants::kSize); |
| 2344 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset)); | 2344 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset)); |
| 2345 sw(fp, MemOperand(sp, StackHandlerConstants::kFPOffset)); | 2345 sw(fp, MemOperand(sp, StackHandlerConstants::kFPOffset)); |
| 2346 sw(cp, MemOperand(sp, StackHandlerConstants::kContextOffset)); | 2346 sw(cp, MemOperand(sp, StackHandlerConstants::kContextOffset)); |
| 2347 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset)); | 2347 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset)); |
| 2348 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset)); | 2348 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset)); |
| 2349 | 2349 |
| 2350 // Link this handler as the new current one. | 2350 // Link this handler as the new current one. |
| 2351 sw(sp, MemOperand(t2)); | 2351 sw(sp, MemOperand(t2)); |
| 2352 | 2352 |
| 2353 } else { | 2353 } else { |
| 2354 // Must preserve a0-a3, and s0 (argv). | 2354 // Must preserve a0-a3, and s0 (argv). |
| 2355 ASSERT(try_location == IN_JS_ENTRY); | 2355 ASSERT(try_location == IN_JS_ENTRY); |
| 2356 // The frame pointer does not point to a JS frame so we save NULL | 2356 // The frame pointer does not point to a JS frame so we save NULL |
| 2357 // for fp. We expect the code throwing an exception to check fp | 2357 // for fp. We expect the code throwing an exception to check fp |
| 2358 // before dereferencing it to restore the context. | 2358 // before dereferencing it to restore the context. |
| 2359 li(t0, Operand(StackHandler::ENTRY)); | 2359 li(t0, Operand(StackHandler::ENTRY)); |
| 2360 | 2360 |
| 2361 // Save the current handler as the next handler. | 2361 // Save the current handler as the next handler. |
| 2362 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 2362 li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| 2363 lw(t1, MemOperand(t2)); | 2363 lw(t1, MemOperand(t2)); |
| 2364 | 2364 |
| 2365 ASSERT(Smi::FromInt(0) == 0); // Used for no context. | 2365 ASSERT(Smi::FromInt(0) == 0); // Used for no context. |
| 2366 | 2366 |
| 2367 addiu(sp, sp, -StackHandlerConstants::kSize); | 2367 addiu(sp, sp, -StackHandlerConstants::kSize); |
| 2368 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset)); | 2368 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset)); |
| 2369 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kFPOffset)); | 2369 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kFPOffset)); |
| 2370 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kContextOffset)); | 2370 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kContextOffset)); |
| 2371 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset)); | 2371 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset)); |
| 2372 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset)); | 2372 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset)); |
| 2373 | 2373 |
| 2374 // Link this handler as the new current one. | 2374 // Link this handler as the new current one. |
| 2375 sw(sp, MemOperand(t2)); | 2375 sw(sp, MemOperand(t2)); |
| 2376 } | 2376 } |
| 2377 } | 2377 } |
| 2378 | 2378 |
| 2379 | 2379 |
| 2380 void MacroAssembler::PopTryHandler() { | 2380 void MacroAssembler::PopTryHandler() { |
| 2381 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 2381 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 2382 pop(a1); | 2382 pop(a1); |
| 2383 Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | 2383 Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| 2384 li(at, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 2384 li(at, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| 2385 sw(a1, MemOperand(at)); | 2385 sw(a1, MemOperand(at)); |
| 2386 } | 2386 } |
| 2387 | 2387 |
| 2388 | 2388 |
| 2389 void MacroAssembler::Throw(Register value) { | 2389 void MacroAssembler::Throw(Register value) { |
| 2390 // v0 is expected to hold the exception. | 2390 // v0 is expected to hold the exception. |
| 2391 Move(v0, value); | 2391 Move(v0, value); |
| 2392 | 2392 |
| 2393 // Adjust this code if not the case. | 2393 // Adjust this code if not the case. |
| 2394 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 2394 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 2395 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | 2395 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2396 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); | 2396 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| 2397 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); | 2397 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| 2398 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); | 2398 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); |
| 2399 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); | 2399 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2400 | 2400 |
| 2401 // Drop the sp to the top of the handler. | 2401 // Drop the sp to the top of the handler. |
| 2402 li(a3, Operand(ExternalReference(Isolate::k_handler_address, | 2402 li(a3, Operand(ExternalReference(Isolate::kHandlerAddress, |
| 2403 isolate()))); | 2403 isolate()))); |
| 2404 lw(sp, MemOperand(a3)); | 2404 lw(sp, MemOperand(a3)); |
| 2405 | 2405 |
| 2406 // Restore the next handler. | 2406 // Restore the next handler. |
| 2407 pop(a2); | 2407 pop(a2); |
| 2408 sw(a2, MemOperand(a3)); | 2408 sw(a2, MemOperand(a3)); |
| 2409 | 2409 |
| 2410 // Restore context and frame pointer, discard state (a3). | 2410 // Restore context and frame pointer, discard state (a3). |
| 2411 MultiPop(a3.bit() | cp.bit() | fp.bit()); | 2411 MultiPop(a3.bit() | cp.bit() | fp.bit()); |
| 2412 | 2412 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2455 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | 2455 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 2456 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); | 2456 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| 2457 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); | 2457 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| 2458 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); | 2458 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); |
| 2459 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); | 2459 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 2460 | 2460 |
| 2461 // v0 is expected to hold the exception. | 2461 // v0 is expected to hold the exception. |
| 2462 Move(v0, value); | 2462 Move(v0, value); |
| 2463 | 2463 |
| 2464 // Drop sp to the top stack handler. | 2464 // Drop sp to the top stack handler. |
| 2465 li(a3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 2465 li(a3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| 2466 lw(sp, MemOperand(a3)); | 2466 lw(sp, MemOperand(a3)); |
| 2467 | 2467 |
| 2468 // Unwind the handlers until the ENTRY handler is found. | 2468 // Unwind the handlers until the ENTRY handler is found. |
| 2469 Label loop, done; | 2469 Label loop, done; |
| 2470 bind(&loop); | 2470 bind(&loop); |
| 2471 // Load the type of the current stack handler. | 2471 // Load the type of the current stack handler. |
| 2472 const int kStateOffset = StackHandlerConstants::kStateOffset; | 2472 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 2473 lw(a2, MemOperand(sp, kStateOffset)); | 2473 lw(a2, MemOperand(sp, kStateOffset)); |
| 2474 Branch(&done, eq, a2, Operand(StackHandler::ENTRY)); | 2474 Branch(&done, eq, a2, Operand(StackHandler::ENTRY)); |
| 2475 // Fetch the next handler in the list. | 2475 // Fetch the next handler in the list. |
| 2476 const int kNextOffset = StackHandlerConstants::kNextOffset; | 2476 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 2477 lw(sp, MemOperand(sp, kNextOffset)); | 2477 lw(sp, MemOperand(sp, kNextOffset)); |
| 2478 jmp(&loop); | 2478 jmp(&loop); |
| 2479 bind(&done); | 2479 bind(&done); |
| 2480 | 2480 |
| 2481 // Set the top handler address to next handler past the current ENTRY handler. | 2481 // Set the top handler address to next handler past the current ENTRY handler. |
| 2482 pop(a2); | 2482 pop(a2); |
| 2483 sw(a2, MemOperand(a3)); | 2483 sw(a2, MemOperand(a3)); |
| 2484 | 2484 |
| 2485 if (type == OUT_OF_MEMORY) { | 2485 if (type == OUT_OF_MEMORY) { |
| 2486 // Set external caught exception to false. | 2486 // Set external caught exception to false. |
| 2487 ExternalReference external_caught( | 2487 ExternalReference external_caught( |
| 2488 Isolate::k_external_caught_exception_address, isolate()); | 2488 Isolate::kExternalCaughtExceptionAddress, isolate()); |
| 2489 li(a0, Operand(false, RelocInfo::NONE)); | 2489 li(a0, Operand(false, RelocInfo::NONE)); |
| 2490 li(a2, Operand(external_caught)); | 2490 li(a2, Operand(external_caught)); |
| 2491 sw(a0, MemOperand(a2)); | 2491 sw(a0, MemOperand(a2)); |
| 2492 | 2492 |
| 2493 // Set pending exception and v0 to out of memory exception. | 2493 // Set pending exception and v0 to out of memory exception. |
| 2494 Failure* out_of_memory = Failure::OutOfMemoryException(); | 2494 Failure* out_of_memory = Failure::OutOfMemoryException(); |
| 2495 li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 2495 li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
| 2496 li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, | 2496 li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 2497 isolate()))); | 2497 isolate()))); |
| 2498 sw(v0, MemOperand(a2)); | 2498 sw(v0, MemOperand(a2)); |
| 2499 } | 2499 } |
| 2500 | 2500 |
| 2501 // Stack layout at this point. See also StackHandlerConstants. | 2501 // Stack layout at this point. See also StackHandlerConstants. |
| 2502 // sp -> state (ENTRY) | 2502 // sp -> state (ENTRY) |
| 2503 // cp | 2503 // cp |
| 2504 // fp | 2504 // fp |
| 2505 // ra | 2505 // ra |
| 2506 | 2506 |
| (...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3966 addiu(fp, sp, 2 * kPointerSize); // Setup new frame pointer. | 3966 addiu(fp, sp, 2 * kPointerSize); // Setup new frame pointer. |
| 3967 | 3967 |
| 3968 if (emit_debug_code()) { | 3968 if (emit_debug_code()) { |
| 3969 sw(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 3969 sw(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 3970 } | 3970 } |
| 3971 | 3971 |
| 3972 li(t8, Operand(CodeObject())); // Accessed from ExitFrame::code_slot. | 3972 li(t8, Operand(CodeObject())); // Accessed from ExitFrame::code_slot. |
| 3973 sw(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 3973 sw(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
| 3974 | 3974 |
| 3975 // Save the frame pointer and the context in top. | 3975 // Save the frame pointer and the context in top. |
| 3976 li(t8, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); | 3976 li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 3977 sw(fp, MemOperand(t8)); | 3977 sw(fp, MemOperand(t8)); |
| 3978 li(t8, Operand(ExternalReference(Isolate::k_context_address, isolate()))); | 3978 li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
| 3979 sw(cp, MemOperand(t8)); | 3979 sw(cp, MemOperand(t8)); |
| 3980 | 3980 |
| 3981 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 3981 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
| 3982 if (save_doubles) { | 3982 if (save_doubles) { |
| 3983 // The stack must be allign to 0 modulo 8 for stores with sdc1. | 3983 // The stack must be allign to 0 modulo 8 for stores with sdc1. |
| 3984 ASSERT(kDoubleSize == frame_alignment); | 3984 ASSERT(kDoubleSize == frame_alignment); |
| 3985 if (frame_alignment > 0) { | 3985 if (frame_alignment > 0) { |
| 3986 ASSERT(IsPowerOf2(frame_alignment)); | 3986 ASSERT(IsPowerOf2(frame_alignment)); |
| 3987 And(sp, sp, Operand(-frame_alignment)); // Align stack. | 3987 And(sp, sp, Operand(-frame_alignment)); // Align stack. |
| 3988 } | 3988 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4018 if (save_doubles) { | 4018 if (save_doubles) { |
| 4019 // Remember: we only need to restore every 2nd double FPU value. | 4019 // Remember: we only need to restore every 2nd double FPU value. |
| 4020 lw(t8, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 4020 lw(t8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 4021 for (int i = 0; i < FPURegister::kNumRegisters; i+=2) { | 4021 for (int i = 0; i < FPURegister::kNumRegisters; i+=2) { |
| 4022 FPURegister reg = FPURegister::from_code(i); | 4022 FPURegister reg = FPURegister::from_code(i); |
| 4023 ldc1(reg, MemOperand(t8, i * kDoubleSize + kPointerSize)); | 4023 ldc1(reg, MemOperand(t8, i * kDoubleSize + kPointerSize)); |
| 4024 } | 4024 } |
| 4025 } | 4025 } |
| 4026 | 4026 |
| 4027 // Clear top frame. | 4027 // Clear top frame. |
| 4028 li(t8, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); | 4028 li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 4029 sw(zero_reg, MemOperand(t8)); | 4029 sw(zero_reg, MemOperand(t8)); |
| 4030 | 4030 |
| 4031 // Restore current context from top and clear it in debug mode. | 4031 // Restore current context from top and clear it in debug mode. |
| 4032 li(t8, Operand(ExternalReference(Isolate::k_context_address, isolate()))); | 4032 li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
| 4033 lw(cp, MemOperand(t8)); | 4033 lw(cp, MemOperand(t8)); |
| 4034 #ifdef DEBUG | 4034 #ifdef DEBUG |
| 4035 sw(a3, MemOperand(t8)); | 4035 sw(a3, MemOperand(t8)); |
| 4036 #endif | 4036 #endif |
| 4037 | 4037 |
| 4038 // Pop the arguments, restore registers, and return. | 4038 // Pop the arguments, restore registers, and return. |
| 4039 mov(sp, fp); // Respect ABI stack constraint. | 4039 mov(sp, fp); // Respect ABI stack constraint. |
| 4040 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); | 4040 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); |
| 4041 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); | 4041 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); |
| 4042 addiu(sp, sp, 8); | 4042 addiu(sp, sp, 8); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4403 opcode == BGTZL); | 4403 opcode == BGTZL); |
| 4404 opcode = (cond == eq) ? BEQ : BNE; | 4404 opcode = (cond == eq) ? BEQ : BNE; |
| 4405 instr = (instr & ~kOpcodeMask) | opcode; | 4405 instr = (instr & ~kOpcodeMask) | opcode; |
| 4406 masm_.emit(instr); | 4406 masm_.emit(instr); |
| 4407 } | 4407 } |
| 4408 | 4408 |
| 4409 | 4409 |
| 4410 } } // namespace v8::internal | 4410 } } // namespace v8::internal |
| 4411 | 4411 |
| 4412 #endif // V8_TARGET_ARCH_MIPS | 4412 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |