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