OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 4414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4425 // After shadowing stops, the original targets are unshadowed and the | 4425 // After shadowing stops, the original targets are unshadowed and the |
4426 // ShadowTargets represent the formerly shadowing targets. | 4426 // ShadowTargets represent the formerly shadowing targets. |
4427 bool has_unlinks = false; | 4427 bool has_unlinks = false; |
4428 for (int i = 0; i < shadows.length(); i++) { | 4428 for (int i = 0; i < shadows.length(); i++) { |
4429 shadows[i]->StopShadowing(); | 4429 shadows[i]->StopShadowing(); |
4430 has_unlinks = has_unlinks || shadows[i]->is_linked(); | 4430 has_unlinks = has_unlinks || shadows[i]->is_linked(); |
4431 } | 4431 } |
4432 function_return_is_shadowed_ = function_return_was_shadowed; | 4432 function_return_is_shadowed_ = function_return_was_shadowed; |
4433 | 4433 |
4434 // Get an external reference to the handler address. | 4434 // Get an external reference to the handler address. |
4435 ExternalReference handler_address(Top::k_handler_address); | 4435 ExternalReference handler_address(Isolate::k_handler_address); |
4436 | 4436 |
4437 // Make sure that there's nothing left on the stack above the | 4437 // Make sure that there's nothing left on the stack above the |
4438 // handler structure. | 4438 // handler structure. |
4439 if (FLAG_debug_code) { | 4439 if (FLAG_debug_code) { |
4440 __ mov(eax, Operand::StaticVariable(handler_address)); | 4440 __ mov(eax, Operand::StaticVariable(handler_address)); |
4441 __ cmp(esp, Operand(eax)); | 4441 __ cmp(esp, Operand(eax)); |
4442 __ Assert(equal, "stack pointer should point to top handler"); | 4442 __ Assert(equal, "stack pointer should point to top handler"); |
4443 } | 4443 } |
4444 | 4444 |
4445 // If we can fall off the end of the try block, unlink from try chain. | 4445 // If we can fall off the end of the try block, unlink from try chain. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4551 // After shadowing stops, the original targets are unshadowed and the | 4551 // After shadowing stops, the original targets are unshadowed and the |
4552 // ShadowTargets represent the formerly shadowing targets. | 4552 // ShadowTargets represent the formerly shadowing targets. |
4553 int nof_unlinks = 0; | 4553 int nof_unlinks = 0; |
4554 for (int i = 0; i < shadows.length(); i++) { | 4554 for (int i = 0; i < shadows.length(); i++) { |
4555 shadows[i]->StopShadowing(); | 4555 shadows[i]->StopShadowing(); |
4556 if (shadows[i]->is_linked()) nof_unlinks++; | 4556 if (shadows[i]->is_linked()) nof_unlinks++; |
4557 } | 4557 } |
4558 function_return_is_shadowed_ = function_return_was_shadowed; | 4558 function_return_is_shadowed_ = function_return_was_shadowed; |
4559 | 4559 |
4560 // Get an external reference to the handler address. | 4560 // Get an external reference to the handler address. |
4561 ExternalReference handler_address(Top::k_handler_address); | 4561 ExternalReference handler_address(Isolate::k_handler_address); |
4562 | 4562 |
4563 // If we can fall off the end of the try block, unlink from the try | 4563 // If we can fall off the end of the try block, unlink from the try |
4564 // chain and set the state on the frame to FALLING. | 4564 // chain and set the state on the frame to FALLING. |
4565 if (has_valid_frame()) { | 4565 if (has_valid_frame()) { |
4566 // The next handler address is on top of the frame. | 4566 // The next handler address is on top of the frame. |
4567 ASSERT(StackHandlerConstants::kNextOffset == 0); | 4567 ASSERT(StackHandlerConstants::kNextOffset == 0); |
4568 frame_->EmitPop(Operand::StaticVariable(handler_address)); | 4568 frame_->EmitPop(Operand::StaticVariable(handler_address)); |
4569 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 4569 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
4570 | 4570 |
4571 // Fake a top of stack value (unneeded when FALLING) and set the | 4571 // Fake a top of stack value (unneeded when FALLING) and set the |
(...skipping 2409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6981 } | 6981 } |
6982 | 6982 |
6983 | 6983 |
6984 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { | 6984 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
6985 ASSERT_EQ(2, args->length()); | 6985 ASSERT_EQ(2, args->length()); |
6986 | 6986 |
6987 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 6987 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
6988 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 6988 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
6989 | 6989 |
6990 Handle<FixedArray> jsfunction_result_caches( | 6990 Handle<FixedArray> jsfunction_result_caches( |
6991 Top::global_context()->jsfunction_result_caches()); | 6991 Isolate::Current()->global_context()->jsfunction_result_caches()); |
6992 if (jsfunction_result_caches->length() <= cache_id) { | 6992 if (jsfunction_result_caches->length() <= cache_id) { |
6993 __ Abort("Attempt to use undefined cache."); | 6993 __ Abort("Attempt to use undefined cache."); |
6994 frame_->Push(Factory::undefined_value()); | 6994 frame_->Push(Factory::undefined_value()); |
6995 return; | 6995 return; |
6996 } | 6996 } |
6997 | 6997 |
6998 Load(args->at(1)); | 6998 Load(args->at(1)); |
6999 Result key = frame_->Pop(); | 6999 Result key = frame_->Pop(); |
7000 key.ToRegister(); | 7000 key.ToRegister(); |
7001 | 7001 |
(...skipping 4452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11454 Label failure; | 11454 Label failure; |
11455 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); | 11455 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); |
11456 __ j(equal, &failure, taken); | 11456 __ j(equal, &failure, taken); |
11457 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); | 11457 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); |
11458 // If not exception it can only be retry. Handle that in the runtime system. | 11458 // If not exception it can only be retry. Handle that in the runtime system. |
11459 __ j(not_equal, &runtime); | 11459 __ j(not_equal, &runtime); |
11460 // Result must now be exception. If there is no pending exception already a | 11460 // Result must now be exception. If there is no pending exception already a |
11461 // stack overflow (on the backtrack stack) was detected in RegExp code but | 11461 // stack overflow (on the backtrack stack) was detected in RegExp code but |
11462 // haven't created the exception yet. Handle that in the runtime system. | 11462 // haven't created the exception yet. Handle that in the runtime system. |
11463 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 11463 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
11464 ExternalReference pending_exception(Top::k_pending_exception_address); | 11464 ExternalReference pending_exception(Isolate::k_pending_exception_address); |
11465 __ mov(eax, | 11465 __ mov(eax, |
11466 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 11466 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
11467 __ cmp(eax, Operand::StaticVariable(pending_exception)); | 11467 __ cmp(eax, Operand::StaticVariable(pending_exception)); |
11468 __ j(equal, &runtime); | 11468 __ j(equal, &runtime); |
11469 __ bind(&failure); | 11469 __ bind(&failure); |
11470 // For failure and exception return null. | 11470 // For failure and exception return null. |
11471 __ mov(Operand(eax), Factory::null_value()); | 11471 __ mov(Operand(eax), Factory::null_value()); |
11472 __ ret(4 * kPointerSize); | 11472 __ ret(4 * kPointerSize); |
11473 | 11473 |
11474 // Load RegExp data. | 11474 // Load RegExp data. |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12019 } | 12019 } |
12020 | 12020 |
12021 | 12021 |
12022 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 12022 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
12023 // eax holds the exception. | 12023 // eax holds the exception. |
12024 | 12024 |
12025 // Adjust this code if not the case. | 12025 // Adjust this code if not the case. |
12026 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 12026 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
12027 | 12027 |
12028 // Drop the sp to the top of the handler. | 12028 // Drop the sp to the top of the handler. |
12029 ExternalReference handler_address(Top::k_handler_address); | 12029 ExternalReference handler_address(Isolate::k_handler_address); |
12030 __ mov(esp, Operand::StaticVariable(handler_address)); | 12030 __ mov(esp, Operand::StaticVariable(handler_address)); |
12031 | 12031 |
12032 // Restore next handler and frame pointer, discard handler state. | 12032 // Restore next handler and frame pointer, discard handler state. |
12033 ASSERT(StackHandlerConstants::kNextOffset == 0); | 12033 ASSERT(StackHandlerConstants::kNextOffset == 0); |
12034 __ pop(Operand::StaticVariable(handler_address)); | 12034 __ pop(Operand::StaticVariable(handler_address)); |
12035 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 12035 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
12036 __ pop(ebp); | 12036 __ pop(ebp); |
12037 __ pop(edx); // Remove state. | 12037 __ pop(edx); // Remove state. |
12038 | 12038 |
12039 // Before returning we restore the context from the frame pointer if | 12039 // Before returning we restore the context from the frame pointer if |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12198 // If the returned exception is RETRY_AFTER_GC continue at retry label | 12198 // If the returned exception is RETRY_AFTER_GC continue at retry label |
12199 ASSERT(Failure::RETRY_AFTER_GC == 0); | 12199 ASSERT(Failure::RETRY_AFTER_GC == 0); |
12200 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 12200 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
12201 __ j(zero, &retry, taken); | 12201 __ j(zero, &retry, taken); |
12202 | 12202 |
12203 // Special handling of out of memory exceptions. | 12203 // Special handling of out of memory exceptions. |
12204 __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 12204 __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
12205 __ j(equal, throw_out_of_memory_exception); | 12205 __ j(equal, throw_out_of_memory_exception); |
12206 | 12206 |
12207 // Retrieve the pending exception and clear the variable. | 12207 // Retrieve the pending exception and clear the variable. |
12208 ExternalReference pending_exception_address(Top::k_pending_exception_address); | 12208 ExternalReference pending_exception_address( |
| 12209 Isolate::k_pending_exception_address); |
12209 __ mov(eax, Operand::StaticVariable(pending_exception_address)); | 12210 __ mov(eax, Operand::StaticVariable(pending_exception_address)); |
12210 __ mov(edx, | 12211 __ mov(edx, |
12211 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 12212 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
12212 __ mov(Operand::StaticVariable(pending_exception_address), edx); | 12213 __ mov(Operand::StaticVariable(pending_exception_address), edx); |
12213 | 12214 |
12214 // Special handling of termination exceptions which are uncatchable | 12215 // Special handling of termination exceptions which are uncatchable |
12215 // by javascript code. | 12216 // by javascript code. |
12216 __ cmp(eax, Factory::termination_exception()); | 12217 __ cmp(eax, Factory::termination_exception()); |
12217 __ j(equal, throw_termination_exception); | 12218 __ j(equal, throw_termination_exception); |
12218 | 12219 |
12219 // Handle normal exception. | 12220 // Handle normal exception. |
12220 __ jmp(throw_normal_exception); | 12221 __ jmp(throw_normal_exception); |
12221 | 12222 |
12222 // Retry. | 12223 // Retry. |
12223 __ bind(&retry); | 12224 __ bind(&retry); |
12224 } | 12225 } |
12225 | 12226 |
12226 | 12227 |
12227 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, | 12228 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, |
12228 UncatchableExceptionType type) { | 12229 UncatchableExceptionType type) { |
12229 // Adjust this code if not the case. | 12230 // Adjust this code if not the case. |
12230 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 12231 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
12231 | 12232 |
12232 // Drop sp to the top stack handler. | 12233 // Drop sp to the top stack handler. |
12233 ExternalReference handler_address(Top::k_handler_address); | 12234 ExternalReference handler_address(Isolate::k_handler_address); |
12234 __ mov(esp, Operand::StaticVariable(handler_address)); | 12235 __ mov(esp, Operand::StaticVariable(handler_address)); |
12235 | 12236 |
12236 // Unwind the handlers until the ENTRY handler is found. | 12237 // Unwind the handlers until the ENTRY handler is found. |
12237 Label loop, done; | 12238 Label loop, done; |
12238 __ bind(&loop); | 12239 __ bind(&loop); |
12239 // Load the type of the current stack handler. | 12240 // Load the type of the current stack handler. |
12240 const int kStateOffset = StackHandlerConstants::kStateOffset; | 12241 const int kStateOffset = StackHandlerConstants::kStateOffset; |
12241 __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | 12242 __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
12242 __ j(equal, &done); | 12243 __ j(equal, &done); |
12243 // Fetch the next handler in the list. | 12244 // Fetch the next handler in the list. |
12244 const int kNextOffset = StackHandlerConstants::kNextOffset; | 12245 const int kNextOffset = StackHandlerConstants::kNextOffset; |
12245 __ mov(esp, Operand(esp, kNextOffset)); | 12246 __ mov(esp, Operand(esp, kNextOffset)); |
12246 __ jmp(&loop); | 12247 __ jmp(&loop); |
12247 __ bind(&done); | 12248 __ bind(&done); |
12248 | 12249 |
12249 // Set the top handler address to next handler past the current ENTRY handler. | 12250 // Set the top handler address to next handler past the current ENTRY handler. |
12250 ASSERT(StackHandlerConstants::kNextOffset == 0); | 12251 ASSERT(StackHandlerConstants::kNextOffset == 0); |
12251 __ pop(Operand::StaticVariable(handler_address)); | 12252 __ pop(Operand::StaticVariable(handler_address)); |
12252 | 12253 |
12253 if (type == OUT_OF_MEMORY) { | 12254 if (type == OUT_OF_MEMORY) { |
12254 // Set external caught exception to false. | 12255 // Set external caught exception to false. |
12255 ExternalReference external_caught(Top::k_external_caught_exception_address); | 12256 ExternalReference external_caught( |
| 12257 Isolate::k_external_caught_exception_address); |
12256 __ mov(eax, false); | 12258 __ mov(eax, false); |
12257 __ mov(Operand::StaticVariable(external_caught), eax); | 12259 __ mov(Operand::StaticVariable(external_caught), eax); |
12258 | 12260 |
12259 // Set pending exception and eax to out of memory exception. | 12261 // Set pending exception and eax to out of memory exception. |
12260 ExternalReference pending_exception(Top::k_pending_exception_address); | 12262 ExternalReference pending_exception(Isolate::k_pending_exception_address); |
12261 __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 12263 __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
12262 __ mov(Operand::StaticVariable(pending_exception), eax); | 12264 __ mov(Operand::StaticVariable(pending_exception), eax); |
12263 } | 12265 } |
12264 | 12266 |
12265 // Clear the context pointer. | 12267 // Clear the context pointer. |
12266 __ xor_(esi, Operand(esi)); | 12268 __ xor_(esi, Operand(esi)); |
12267 | 12269 |
12268 // Restore fp from handler and discard handler state. | 12270 // Restore fp from handler and discard handler state. |
12269 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 12271 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
12270 __ pop(ebp); | 12272 __ pop(ebp); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12351 // Push marker in two places. | 12353 // Push marker in two places. |
12352 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 12354 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
12353 __ push(Immediate(Smi::FromInt(marker))); // context slot | 12355 __ push(Immediate(Smi::FromInt(marker))); // context slot |
12354 __ push(Immediate(Smi::FromInt(marker))); // function slot | 12356 __ push(Immediate(Smi::FromInt(marker))); // function slot |
12355 // Save callee-saved registers (C calling conventions). | 12357 // Save callee-saved registers (C calling conventions). |
12356 __ push(edi); | 12358 __ push(edi); |
12357 __ push(esi); | 12359 __ push(esi); |
12358 __ push(ebx); | 12360 __ push(ebx); |
12359 | 12361 |
12360 // Save copies of the top frame descriptor on the stack. | 12362 // Save copies of the top frame descriptor on the stack. |
12361 ExternalReference c_entry_fp(Top::k_c_entry_fp_address); | 12363 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address); |
12362 __ push(Operand::StaticVariable(c_entry_fp)); | 12364 __ push(Operand::StaticVariable(c_entry_fp)); |
12363 | 12365 |
12364 #ifdef ENABLE_LOGGING_AND_PROFILING | 12366 #ifdef ENABLE_LOGGING_AND_PROFILING |
12365 // If this is the outermost JS call, set js_entry_sp value. | 12367 // If this is the outermost JS call, set js_entry_sp value. |
12366 ExternalReference js_entry_sp(Top::k_js_entry_sp_address); | 12368 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address); |
12367 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 12369 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
12368 __ j(not_equal, ¬_outermost_js); | 12370 __ j(not_equal, ¬_outermost_js); |
12369 __ mov(Operand::StaticVariable(js_entry_sp), ebp); | 12371 __ mov(Operand::StaticVariable(js_entry_sp), ebp); |
12370 __ bind(¬_outermost_js); | 12372 __ bind(¬_outermost_js); |
12371 #endif | 12373 #endif |
12372 | 12374 |
12373 // Call a faked try-block that does the invoke. | 12375 // Call a faked try-block that does the invoke. |
12374 __ call(&invoke); | 12376 __ call(&invoke); |
12375 | 12377 |
12376 // Caught exception: Store result (exception) in the pending | 12378 // Caught exception: Store result (exception) in the pending |
12377 // exception field in the JSEnv and return a failure sentinel. | 12379 // exception field in the JSEnv and return a failure sentinel. |
12378 ExternalReference pending_exception(Top::k_pending_exception_address); | 12380 ExternalReference pending_exception(Isolate::k_pending_exception_address); |
12379 __ mov(Operand::StaticVariable(pending_exception), eax); | 12381 __ mov(Operand::StaticVariable(pending_exception), eax); |
12380 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); | 12382 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); |
12381 __ jmp(&exit); | 12383 __ jmp(&exit); |
12382 | 12384 |
12383 // Invoke: Link this frame into the handler chain. | 12385 // Invoke: Link this frame into the handler chain. |
12384 __ bind(&invoke); | 12386 __ bind(&invoke); |
12385 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); | 12387 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); |
12386 | 12388 |
12387 // Clear any pending exceptions. | 12389 // Clear any pending exceptions. |
12388 __ mov(edx, | 12390 __ mov(edx, |
(...skipping 12 matching lines...) Expand all Loading... |
12401 __ mov(edx, Immediate(construct_entry)); | 12403 __ mov(edx, Immediate(construct_entry)); |
12402 } else { | 12404 } else { |
12403 ExternalReference entry(Builtins::JSEntryTrampoline); | 12405 ExternalReference entry(Builtins::JSEntryTrampoline); |
12404 __ mov(edx, Immediate(entry)); | 12406 __ mov(edx, Immediate(entry)); |
12405 } | 12407 } |
12406 __ mov(edx, Operand(edx, 0)); // deref address | 12408 __ mov(edx, Operand(edx, 0)); // deref address |
12407 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 12409 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
12408 __ call(Operand(edx)); | 12410 __ call(Operand(edx)); |
12409 | 12411 |
12410 // Unlink this frame from the handler chain. | 12412 // Unlink this frame from the handler chain. |
12411 __ pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address))); | 12413 __ pop(Operand::StaticVariable( |
| 12414 ExternalReference(Isolate::k_handler_address))); |
12412 // Pop next_sp. | 12415 // Pop next_sp. |
12413 __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 12416 __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |
12414 | 12417 |
12415 #ifdef ENABLE_LOGGING_AND_PROFILING | 12418 #ifdef ENABLE_LOGGING_AND_PROFILING |
12416 // If current EBP value is the same as js_entry_sp value, it means that | 12419 // If current EBP value is the same as js_entry_sp value, it means that |
12417 // the current function is the outermost. | 12420 // the current function is the outermost. |
12418 __ cmp(ebp, Operand::StaticVariable(js_entry_sp)); | 12421 __ cmp(ebp, Operand::StaticVariable(js_entry_sp)); |
12419 __ j(not_equal, ¬_outermost_js_2); | 12422 __ j(not_equal, ¬_outermost_js_2); |
12420 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 12423 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
12421 __ bind(¬_outermost_js_2); | 12424 __ bind(¬_outermost_js_2); |
12422 #endif | 12425 #endif |
12423 | 12426 |
12424 // Restore the top frame descriptor from the stack. | 12427 // Restore the top frame descriptor from the stack. |
12425 __ bind(&exit); | 12428 __ bind(&exit); |
12426 __ pop(Operand::StaticVariable(ExternalReference(Top::k_c_entry_fp_address))); | 12429 __ pop(Operand::StaticVariable( |
| 12430 ExternalReference(Isolate::k_c_entry_fp_address))); |
12427 | 12431 |
12428 // Restore callee-saved registers (C calling conventions). | 12432 // Restore callee-saved registers (C calling conventions). |
12429 __ pop(ebx); | 12433 __ pop(ebx); |
12430 __ pop(esi); | 12434 __ pop(esi); |
12431 __ pop(edi); | 12435 __ pop(edi); |
12432 __ add(Operand(esp), Immediate(2 * kPointerSize)); // remove markers | 12436 __ add(Operand(esp), Immediate(2 * kPointerSize)); // remove markers |
12433 | 12437 |
12434 // Restore frame pointer and return. | 12438 // Restore frame pointer and return. |
12435 __ pop(ebp); | 12439 __ pop(ebp); |
12436 __ ret(0); | 12440 __ ret(0); |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13718 masm.GetCode(&desc); | 13722 masm.GetCode(&desc); |
13719 // Call the function from C++. | 13723 // Call the function from C++. |
13720 return FUNCTION_CAST<MemCopyFunction>(buffer); | 13724 return FUNCTION_CAST<MemCopyFunction>(buffer); |
13721 } | 13725 } |
13722 | 13726 |
13723 #undef __ | 13727 #undef __ |
13724 | 13728 |
13725 } } // namespace v8::internal | 13729 } } // namespace v8::internal |
13726 | 13730 |
13727 #endif // V8_TARGET_ARCH_IA32 | 13731 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |