| 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 707 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   718  |   718  | 
|   719 void MacroAssembler::LeaveApiExitFrame() { |   719 void MacroAssembler::LeaveApiExitFrame() { | 
|   720   mov(esp, ebp); |   720   mov(esp, ebp); | 
|   721   pop(ebp); |   721   pop(ebp); | 
|   722  |   722  | 
|   723   LeaveExitFrameEpilogue(); |   723   LeaveExitFrameEpilogue(); | 
|   724 } |   724 } | 
|   725  |   725  | 
|   726  |   726  | 
|   727 void MacroAssembler::PushTryHandler(CodeLocation try_location, |   727 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 
|   728                                     HandlerType type) { |   728                                     HandlerType type, | 
 |   729                                     int handler_index) { | 
|   729   // Adjust this code if not the case. |   730   // Adjust this code if not the case. | 
|   730   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |   731   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 
|   731   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |   732   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 
|   732   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |   733   STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | 
|   733   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |   734   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | 
|   734   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |   735   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | 
|   735   STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |   736   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | 
|   736   // The pc (return address) is already on TOS. |   737  | 
 |   738   // We will build up the handler from the bottom by pushing on the stack. | 
 |   739   // First compute the state and push the frame pointer and context. | 
 |   740   unsigned state = StackHandler::OffsetField::encode(handler_index); | 
|   737   if (try_location == IN_JAVASCRIPT) { |   741   if (try_location == IN_JAVASCRIPT) { | 
|   738     if (type == TRY_CATCH_HANDLER) { |  | 
|   739       push(Immediate(StackHandler::TRY_CATCH)); |  | 
|   740     } else { |  | 
|   741       push(Immediate(StackHandler::TRY_FINALLY)); |  | 
|   742     } |  | 
|   743     push(ebp); |   742     push(ebp); | 
|   744     push(esi); |   743     push(esi); | 
 |   744     state |= (type == TRY_CATCH_HANDLER) | 
 |   745         ? StackHandler::KindField::encode(StackHandler::TRY_CATCH) | 
 |   746         : StackHandler::KindField::encode(StackHandler::TRY_FINALLY); | 
|   745   } else { |   747   } else { | 
|   746     ASSERT(try_location == IN_JS_ENTRY); |   748     ASSERT(try_location == IN_JS_ENTRY); | 
|   747     // The frame pointer does not point to a JS frame so we save NULL |   749     // The frame pointer does not point to a JS frame so we save NULL for | 
|   748     // for ebp. We expect the code throwing an exception to check ebp |   750     // ebp. We expect the code throwing an exception to check ebp before | 
|   749     // before dereferencing it to restore the context. |   751     // dereferencing it to restore the context. | 
|   750     push(Immediate(StackHandler::ENTRY)); |  | 
|   751     push(Immediate(0));  // NULL frame pointer. |   752     push(Immediate(0));  // NULL frame pointer. | 
|   752     push(Immediate(Smi::FromInt(0)));  // No context. |   753     push(Immediate(Smi::FromInt(0)));  // No context. | 
 |   754     state |= StackHandler::KindField::encode(StackHandler::ENTRY); | 
|   753   } |   755   } | 
|   754   // Save the current handler as the next handler. |   756  | 
|   755   push(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, |   757   // Push the state and the code object. | 
|   756                                                  isolate()))); |   758   push(Immediate(state)); | 
|   757   // Link this handler as the new current one. |   759   push(CodeObject()); | 
|   758   mov(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, |   760  | 
|   759                                                 isolate())), |   761   // Link the current handler as the next handler. | 
|   760       esp); |   762   ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 
 |   763   push(Operand::StaticVariable(handler_address)); | 
 |   764   // Set this new handler as the current one. | 
 |   765   mov(Operand::StaticVariable(handler_address), esp); | 
|   761 } |   766 } | 
|   762  |   767  | 
|   763  |   768  | 
|   764 void MacroAssembler::PopTryHandler() { |   769 void MacroAssembler::PopTryHandler() { | 
|   765   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |   770   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 
|   766   pop(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, |   771   ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 
|   767                                                 isolate()))); |   772   pop(Operand::StaticVariable(handler_address)); | 
|   768   add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |   773   add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 
|   769 } |   774 } | 
|   770  |   775  | 
|   771  |   776  | 
 |   777 void MacroAssembler::JumpToHandlerEntry() { | 
 |   778   // Compute the handler entry address and jump to it.  The handler table is | 
 |   779   // a fixed array of (smi-tagged) code offsets. | 
 |   780   // eax = exception, edi = code object, edx = state. | 
 |   781   mov(ebx, FieldOperand(edi, Code::kHandlerTableOffset)); | 
 |   782   shr(edx, StackHandler::kKindWidth); | 
 |   783   mov(edx, FieldOperand(ebx, edx, times_4, FixedArray::kHeaderSize)); | 
 |   784   SmiUntag(edx); | 
 |   785   lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); | 
 |   786   jmp(edi); | 
 |   787 } | 
 |   788  | 
 |   789  | 
|   772 void MacroAssembler::Throw(Register value) { |   790 void MacroAssembler::Throw(Register value) { | 
|   773   // Adjust this code if not the case. |   791   // Adjust this code if not the case. | 
|   774   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |   792   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 
|   775   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |   793   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 
|   776   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |   794   STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | 
|   777   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |   795   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | 
|   778   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |   796   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | 
|   779   STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |   797   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | 
|   780   // eax must hold the exception. |   798  | 
 |   799   // The exception is expected in eax. | 
|   781   if (!value.is(eax)) { |   800   if (!value.is(eax)) { | 
|   782     mov(eax, value); |   801     mov(eax, value); | 
|   783   } |   802   } | 
 |   803   // Drop the stack pointer to the top of the top handler. | 
 |   804   ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 
 |   805   mov(esp, Operand::StaticVariable(handler_address)); | 
 |   806   // Restore the next handler. | 
 |   807   pop(Operand::StaticVariable(handler_address)); | 
|   784  |   808  | 
|   785   // Drop the sp to the top of the handler. |   809   // Remove the code object and state, compute the handler address in edi. | 
|   786   ExternalReference handler_address(Isolate::kHandlerAddress, |   810   pop(edi);  // Code object. | 
|   787                                     isolate()); |   811   pop(edx);  // Index and state. | 
|   788   mov(esp, Operand::StaticVariable(handler_address)); |  | 
|   789  |   812  | 
|   790   // Restore next handler, context, and frame pointer; discard handler state. |   813   // Restore the context and frame pointer. | 
|   791   pop(Operand::StaticVariable(handler_address)); |  | 
|   792   pop(esi);  // Context. |   814   pop(esi);  // Context. | 
|   793   pop(ebp);  // Frame pointer. |   815   pop(ebp);  // Frame pointer. | 
|   794   pop(edx);  // State. |  | 
|   795  |   816  | 
|   796   // If the handler is a JS frame, restore the context to the frame. |   817   // If the handler is a JS frame, restore the context to the frame. | 
|   797   // (edx == ENTRY) == (ebp == 0) == (esi == 0), so we could test any |   818   // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either | 
|   798   // of them. |   819   // ebp or esi. | 
|   799   Label skip; |   820   Label skip; | 
|   800   cmp(edx, Immediate(StackHandler::ENTRY)); |   821   test(esi, esi); | 
|   801   j(equal, &skip, Label::kNear); |   822   j(zero, &skip, Label::kNear); | 
|   802   mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |   823   mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); | 
|   803   bind(&skip); |   824   bind(&skip); | 
|   804  |   825  | 
|   805   ret(0); |   826   JumpToHandlerEntry(); | 
|   806 } |   827 } | 
|   807  |   828  | 
|   808  |   829  | 
|   809 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |   830 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 
|   810                                       Register value) { |   831                                       Register value) { | 
|   811   // Adjust this code if not the case. |   832   // Adjust this code if not the case. | 
|   812   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |   833   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 
|   813   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |   834   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 
|   814   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |   835   STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | 
|   815   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |   836   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | 
|   816   STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |   837   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | 
|   817   STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |   838   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | 
|   818  |   839  | 
|   819   // The exception is expected in eax. |   840   // The exception is expected in eax. | 
|   820   if (type == OUT_OF_MEMORY) { |   841   if (type == OUT_OF_MEMORY) { | 
|   821     // Set external caught exception to false. |   842     // Set external caught exception to false. | 
|   822     ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, |   843     ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, | 
|   823                                       isolate()); |   844                                       isolate()); | 
|   824     mov(Operand::StaticVariable(external_caught), Immediate(false)); |   845     mov(Operand::StaticVariable(external_caught), Immediate(false)); | 
|   825  |   846  | 
|   826     // Set pending exception and eax to out of memory exception. |   847     // Set pending exception and eax to out of memory exception. | 
|   827     ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |   848     ExternalReference pending_exception(Isolate::kPendingExceptionAddress, | 
|   828                                         isolate()); |   849                                         isolate()); | 
|   829     mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |   850     mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 
|   830     mov(Operand::StaticVariable(pending_exception), eax); |   851     mov(Operand::StaticVariable(pending_exception), eax); | 
|   831   } else if (!value.is(eax)) { |   852   } else if (!value.is(eax)) { | 
|   832     mov(eax, value); |   853     mov(eax, value); | 
|   833   } |   854   } | 
|   834  |   855  | 
|   835   // Drop the stack pointer to the top of the top stack handler. |   856   // Drop the stack pointer to the top of the top stack handler. | 
|   836   ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |   857   ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 
|   837   mov(esp, Operand::StaticVariable(handler_address)); |   858   mov(esp, Operand::StaticVariable(handler_address)); | 
|   838  |   859  | 
|   839   // Unwind the handlers until the top ENTRY handler is found. |   860   // Unwind the handlers until the top ENTRY handler is found. | 
|   840   Label fetch_next, check_kind; |   861   Label fetch_next, check_kind; | 
|   841   jmp(&check_kind, Label::kNear); |   862   jmp(&check_kind, Label::kNear); | 
|   842   bind(&fetch_next); |   863   bind(&fetch_next); | 
|   843   mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); |   864   mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); | 
|   844  |   865  | 
|   845   bind(&check_kind); |   866   bind(&check_kind); | 
|   846   cmp(Operand(esp, StackHandlerConstants::kStateOffset), |   867   STATIC_ASSERT(StackHandler::ENTRY == 0); | 
|   847       Immediate(StackHandler::ENTRY)); |   868   test(Operand(esp, StackHandlerConstants::kStateOffset), | 
|   848   j(not_equal, &fetch_next); |   869        Immediate(StackHandler::KindField::kMask)); | 
 |   870   j(not_zero, &fetch_next); | 
|   849  |   871  | 
|   850   // Set the top handler address to next handler past the top ENTRY handler. |   872   // Set the top handler address to next handler past the top ENTRY handler. | 
|   851   pop(Operand::StaticVariable(handler_address)); |   873   pop(Operand::StaticVariable(handler_address)); | 
|   852  |   874  | 
|   853   // Clear the context and frame pointer (0 was saved in the handler), and |   875   // Remove the code object and state, compute the handler address in edi. | 
|   854   // discard the state. |   876   pop(edi);  // Code object. | 
 |   877   pop(edx);  // Index and state. | 
 |   878  | 
 |   879   // Clear the context pointer and frame pointer (0 was saved in the handler). | 
|   855   pop(esi); |   880   pop(esi); | 
|   856   pop(ebp); |   881   pop(ebp); | 
|   857   pop(edx);  // State. |  | 
|   858  |   882  | 
|   859   ret(0); |   883   JumpToHandlerEntry(); | 
|   860 } |   884 } | 
|   861  |   885  | 
|   862  |   886  | 
|   863 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |   887 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 
|   864                                             Register scratch, |   888                                             Register scratch, | 
|   865                                             Label* miss) { |   889                                             Label* miss) { | 
|   866   Label same_contexts; |   890   Label same_contexts; | 
|   867  |   891  | 
|   868   ASSERT(!holder_reg.is(scratch)); |   892   ASSERT(!holder_reg.is(scratch)); | 
|   869  |   893  | 
| (...skipping 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2636     cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); |  2660     cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); | 
|  2637     Check(less_equal, "Live Bytes Count overflow chunk size"); |  2661     Check(less_equal, "Live Bytes Count overflow chunk size"); | 
|  2638   } |  2662   } | 
|  2639  |  2663  | 
|  2640   bind(&done); |  2664   bind(&done); | 
|  2641 } |  2665 } | 
|  2642  |  2666  | 
|  2643 } }  // namespace v8::internal |  2667 } }  // namespace v8::internal | 
|  2644  |  2668  | 
|  2645 #endif  // V8_TARGET_ARCH_IA32 |  2669 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |