OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 // Get the return address from the stack and restore the frame pointer. | 1108 // Get the return address from the stack and restore the frame pointer. |
1109 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 1109 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
1110 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 1110 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
1111 | 1111 |
1112 // Pop the arguments and the receiver from the caller stack. | 1112 // Pop the arguments and the receiver from the caller stack. |
1113 lea(esp, Operand(esi, 1 * kPointerSize)); | 1113 lea(esp, Operand(esi, 1 * kPointerSize)); |
1114 | 1114 |
1115 // Push the return address to get ready to return. | 1115 // Push the return address to get ready to return. |
1116 push(ecx); | 1116 push(ecx); |
1117 | 1117 |
1118 LeaveExitFrameEpilogue(); | 1118 LeaveExitFrameEpilogue(true); |
1119 } | 1119 } |
1120 | 1120 |
1121 | 1121 |
1122 void MacroAssembler::LeaveExitFrameEpilogue() { | 1122 void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { |
1123 // Restore current context from top and clear it in debug mode. | 1123 // Restore current context from top and clear it in debug mode. |
1124 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 1124 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
1125 mov(esi, Operand::StaticVariable(context_address)); | 1125 if (restore_context) { |
| 1126 mov(esi, Operand::StaticVariable(context_address)); |
| 1127 } |
1126 #ifdef DEBUG | 1128 #ifdef DEBUG |
1127 mov(Operand::StaticVariable(context_address), Immediate(0)); | 1129 mov(Operand::StaticVariable(context_address), Immediate(0)); |
1128 #endif | 1130 #endif |
1129 | 1131 |
1130 // Clear the top frame. | 1132 // Clear the top frame. |
1131 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, | 1133 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, |
1132 isolate()); | 1134 isolate()); |
1133 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | 1135 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); |
1134 } | 1136 } |
1135 | 1137 |
1136 | 1138 |
1137 void MacroAssembler::LeaveApiExitFrame() { | 1139 void MacroAssembler::LeaveApiExitFrame(bool restore_context) { |
1138 mov(esp, ebp); | 1140 mov(esp, ebp); |
1139 pop(ebp); | 1141 pop(ebp); |
1140 | 1142 |
1141 LeaveExitFrameEpilogue(); | 1143 LeaveExitFrameEpilogue(restore_context); |
1142 } | 1144 } |
1143 | 1145 |
1144 | 1146 |
1145 void MacroAssembler::PushTryHandler(StackHandler::Kind kind, | 1147 void MacroAssembler::PushTryHandler(StackHandler::Kind kind, |
1146 int handler_index) { | 1148 int handler_index) { |
1147 // Adjust this code if not the case. | 1149 // Adjust this code if not the case. |
1148 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | 1150 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
1149 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 1151 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
1150 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | 1152 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); |
1151 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | 1153 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 | 2222 |
2221 | 2223 |
2222 void MacroAssembler::PrepareCallApiFunction(int argc) { | 2224 void MacroAssembler::PrepareCallApiFunction(int argc) { |
2223 EnterApiExitFrame(argc); | 2225 EnterApiExitFrame(argc); |
2224 if (emit_debug_code()) { | 2226 if (emit_debug_code()) { |
2225 mov(esi, Immediate(BitCast<int32_t>(kZapValue))); | 2227 mov(esi, Immediate(BitCast<int32_t>(kZapValue))); |
2226 } | 2228 } |
2227 } | 2229 } |
2228 | 2230 |
2229 | 2231 |
2230 void MacroAssembler::CallApiFunctionAndReturn(Address function_address, | 2232 void MacroAssembler::CallApiFunctionAndReturn( |
2231 Address thunk_address, | 2233 Address function_address, |
2232 Operand thunk_last_arg, | 2234 Address thunk_address, |
2233 int stack_space, | 2235 Operand thunk_last_arg, |
2234 int return_value_offset) { | 2236 int stack_space, |
| 2237 Operand return_value_operand, |
| 2238 Operand* context_restore_operand) { |
2235 ExternalReference next_address = | 2239 ExternalReference next_address = |
2236 ExternalReference::handle_scope_next_address(isolate()); | 2240 ExternalReference::handle_scope_next_address(isolate()); |
2237 ExternalReference limit_address = | 2241 ExternalReference limit_address = |
2238 ExternalReference::handle_scope_limit_address(isolate()); | 2242 ExternalReference::handle_scope_limit_address(isolate()); |
2239 ExternalReference level_address = | 2243 ExternalReference level_address = |
2240 ExternalReference::handle_scope_level_address(isolate()); | 2244 ExternalReference::handle_scope_level_address(isolate()); |
2241 | 2245 |
2242 // Allocate HandleScope in callee-save registers. | 2246 // Allocate HandleScope in callee-save registers. |
2243 mov(ebx, Operand::StaticVariable(next_address)); | 2247 mov(ebx, Operand::StaticVariable(next_address)); |
2244 mov(edi, Operand::StaticVariable(limit_address)); | 2248 mov(edi, Operand::StaticVariable(limit_address)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 PushSafepointRegisters(); | 2284 PushSafepointRegisters(); |
2281 PrepareCallCFunction(1, eax); | 2285 PrepareCallCFunction(1, eax); |
2282 mov(Operand(esp, 0), | 2286 mov(Operand(esp, 0), |
2283 Immediate(ExternalReference::isolate_address(isolate()))); | 2287 Immediate(ExternalReference::isolate_address(isolate()))); |
2284 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | 2288 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); |
2285 PopSafepointRegisters(); | 2289 PopSafepointRegisters(); |
2286 } | 2290 } |
2287 | 2291 |
2288 Label prologue; | 2292 Label prologue; |
2289 // Load the value from ReturnValue | 2293 // Load the value from ReturnValue |
2290 mov(eax, Operand(ebp, return_value_offset * kPointerSize)); | 2294 mov(eax, return_value_operand); |
2291 | 2295 |
2292 Label promote_scheduled_exception; | 2296 Label promote_scheduled_exception; |
| 2297 Label exception_handled; |
2293 Label delete_allocated_handles; | 2298 Label delete_allocated_handles; |
2294 Label leave_exit_frame; | 2299 Label leave_exit_frame; |
2295 | 2300 |
2296 bind(&prologue); | 2301 bind(&prologue); |
2297 // No more valid handles (the result handle was the last one). Restore | 2302 // No more valid handles (the result handle was the last one). Restore |
2298 // previous handle scope. | 2303 // previous handle scope. |
2299 mov(Operand::StaticVariable(next_address), ebx); | 2304 mov(Operand::StaticVariable(next_address), ebx); |
2300 sub(Operand::StaticVariable(level_address), Immediate(1)); | 2305 sub(Operand::StaticVariable(level_address), Immediate(1)); |
2301 Assert(above_equal, kInvalidHandleScopeLevel); | 2306 Assert(above_equal, kInvalidHandleScopeLevel); |
2302 cmp(edi, Operand::StaticVariable(limit_address)); | 2307 cmp(edi, Operand::StaticVariable(limit_address)); |
2303 j(not_equal, &delete_allocated_handles); | 2308 j(not_equal, &delete_allocated_handles); |
2304 bind(&leave_exit_frame); | 2309 bind(&leave_exit_frame); |
2305 | 2310 |
2306 // Check if the function scheduled an exception. | 2311 // Check if the function scheduled an exception. |
2307 ExternalReference scheduled_exception_address = | 2312 ExternalReference scheduled_exception_address = |
2308 ExternalReference::scheduled_exception_address(isolate()); | 2313 ExternalReference::scheduled_exception_address(isolate()); |
2309 cmp(Operand::StaticVariable(scheduled_exception_address), | 2314 cmp(Operand::StaticVariable(scheduled_exception_address), |
2310 Immediate(isolate()->factory()->the_hole_value())); | 2315 Immediate(isolate()->factory()->the_hole_value())); |
2311 j(not_equal, &promote_scheduled_exception); | 2316 j(not_equal, &promote_scheduled_exception); |
| 2317 bind(&exception_handled); |
2312 | 2318 |
2313 #if ENABLE_EXTRA_CHECKS | 2319 #if ENABLE_EXTRA_CHECKS |
2314 // Check if the function returned a valid JavaScript value. | 2320 // Check if the function returned a valid JavaScript value. |
2315 Label ok; | 2321 Label ok; |
2316 Register return_value = eax; | 2322 Register return_value = eax; |
2317 Register map = ecx; | 2323 Register map = ecx; |
2318 | 2324 |
2319 JumpIfSmi(return_value, &ok, Label::kNear); | 2325 JumpIfSmi(return_value, &ok, Label::kNear); |
2320 mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); | 2326 mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); |
2321 | 2327 |
(...skipping 16 matching lines...) Expand all Loading... |
2338 j(equal, &ok, Label::kNear); | 2344 j(equal, &ok, Label::kNear); |
2339 | 2345 |
2340 cmp(return_value, isolate()->factory()->null_value()); | 2346 cmp(return_value, isolate()->factory()->null_value()); |
2341 j(equal, &ok, Label::kNear); | 2347 j(equal, &ok, Label::kNear); |
2342 | 2348 |
2343 Abort(kAPICallReturnedInvalidObject); | 2349 Abort(kAPICallReturnedInvalidObject); |
2344 | 2350 |
2345 bind(&ok); | 2351 bind(&ok); |
2346 #endif | 2352 #endif |
2347 | 2353 |
2348 LeaveApiExitFrame(); | 2354 bool restore_context = context_restore_operand != NULL; |
| 2355 if (restore_context) { |
| 2356 mov(esi, *context_restore_operand); |
| 2357 } |
| 2358 LeaveApiExitFrame(!restore_context); |
2349 ret(stack_space * kPointerSize); | 2359 ret(stack_space * kPointerSize); |
2350 | 2360 |
2351 bind(&promote_scheduled_exception); | 2361 bind(&promote_scheduled_exception); |
2352 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 2362 CallRuntime(Runtime::kPromoteScheduledException, 0); |
| 2363 jmp(&exception_handled); |
2353 | 2364 |
2354 // HandleScope limit has changed. Delete allocated extensions. | 2365 // HandleScope limit has changed. Delete allocated extensions. |
2355 ExternalReference delete_extensions = | 2366 ExternalReference delete_extensions = |
2356 ExternalReference::delete_handle_scope_extensions(isolate()); | 2367 ExternalReference::delete_handle_scope_extensions(isolate()); |
2357 bind(&delete_allocated_handles); | 2368 bind(&delete_allocated_handles); |
2358 mov(Operand::StaticVariable(limit_address), edi); | 2369 mov(Operand::StaticVariable(limit_address), edi); |
2359 mov(edi, eax); | 2370 mov(edi, eax); |
2360 mov(Operand(esp, 0), | 2371 mov(Operand(esp, 0), |
2361 Immediate(ExternalReference::isolate_address(isolate()))); | 2372 Immediate(ExternalReference::isolate_address(isolate()))); |
2362 mov(eax, Immediate(delete_extensions)); | 2373 mov(eax, Immediate(delete_extensions)); |
(...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3430 j(greater, &no_memento_available); | 3441 j(greater, &no_memento_available); |
3431 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), | 3442 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), |
3432 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map()))); | 3443 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map()))); |
3433 bind(&no_memento_available); | 3444 bind(&no_memento_available); |
3434 } | 3445 } |
3435 | 3446 |
3436 | 3447 |
3437 } } // namespace v8::internal | 3448 } } // namespace v8::internal |
3438 | 3449 |
3439 #endif // V8_TARGET_ARCH_IA32 | 3450 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |