OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 5186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5197 // debugger. See VisitReturnStatement for the full return sequence. | 5197 // debugger. See VisitReturnStatement for the full return sequence. |
5198 __ mov(esp, Operand(ebp)); | 5198 __ mov(esp, Operand(ebp)); |
5199 __ pop(ebp); | 5199 __ pop(ebp); |
5200 } | 5200 } |
5201 | 5201 |
5202 | 5202 |
5203 #undef __ | 5203 #undef __ |
5204 #define __ masm-> | 5204 #define __ masm-> |
5205 | 5205 |
5206 | 5206 |
5207 void CEntryStub::GenerateReserveCParameterSpace(MacroAssembler* masm, | |
5208 int num_parameters) { | |
5209 if (num_parameters > 0) { | |
5210 __ sub(Operand(esp), Immediate(num_parameters * kPointerSize)); | |
5211 } | |
5212 static const int kFrameAlignment = OS::ActivationFrameAlignment(); | |
5213 if (kFrameAlignment > 0) { | |
5214 ASSERT(IsPowerOf2(kFrameAlignment)); | |
5215 __ and_(esp, -kFrameAlignment); | |
5216 } | |
5217 } | |
5218 | |
5219 | |
5220 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 5207 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
5221 ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code | 5208 ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code |
5222 ExternalReference handler_address(Top::k_handler_address); | 5209 ExternalReference handler_address(Top::k_handler_address); |
5223 __ mov(edx, Operand::StaticVariable(handler_address)); | 5210 __ mov(edx, Operand::StaticVariable(handler_address)); |
5224 __ mov(ecx, Operand(edx, -1 * kPointerSize)); // get next in chain | 5211 __ mov(ecx, Operand(edx, -1 * kPointerSize)); // get next in chain |
5225 __ mov(Operand::StaticVariable(handler_address), ecx); | 5212 __ mov(Operand::StaticVariable(handler_address), ecx); |
5226 __ mov(esp, Operand(edx)); | 5213 __ mov(esp, Operand(edx)); |
5227 __ pop(edi); | 5214 __ pop(edi); |
5228 __ pop(ebp); | 5215 __ pop(ebp); |
5229 __ pop(edx); // remove code pointer | 5216 __ pop(edx); // remove code pointer |
5230 __ pop(edx); // remove state | 5217 __ pop(edx); // remove state |
5231 | 5218 |
5232 // Before returning we restore the context from the frame pointer if not NULL. | 5219 // Before returning we restore the context from the frame pointer if not NULL. |
5233 // The frame pointer is NULL in the exception handler of a JS entry frame. | 5220 // The frame pointer is NULL in the exception handler of a JS entry frame. |
5234 __ xor_(esi, Operand(esi)); // tentatively set context pointer to NULL | 5221 __ xor_(esi, Operand(esi)); // tentatively set context pointer to NULL |
5235 Label skip; | 5222 Label skip; |
5236 __ cmp(ebp, 0); | 5223 __ cmp(ebp, 0); |
5237 __ j(equal, &skip, not_taken); | 5224 __ j(equal, &skip, not_taken); |
5238 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 5225 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
5239 __ bind(&skip); | 5226 __ bind(&skip); |
5240 | 5227 |
5241 __ ret(0); | 5228 __ ret(0); |
5242 } | 5229 } |
5243 | 5230 |
5244 | 5231 |
5245 void CEntryStub::GenerateCore(MacroAssembler* masm, | 5232 void CEntryStub::GenerateCore(MacroAssembler* masm, |
5246 Label* throw_normal_exception, | 5233 Label* throw_normal_exception, |
5247 Label* throw_out_of_memory_exception, | 5234 Label* throw_out_of_memory_exception, |
5248 bool do_gc, | 5235 StackFrame::Type frame_type, |
5249 bool do_restore) { | 5236 bool do_gc) { |
5250 // eax: result parameter for PerformGC, if any | 5237 // eax: result parameter for PerformGC, if any |
5251 // ebx: pointer to C function (C callee-saved) | 5238 // ebx: pointer to C function (C callee-saved) |
5252 // ebp: frame pointer (restored after C call) | 5239 // ebp: frame pointer (restored after C call) |
5253 // esp: stack pointer (restored after C call) | 5240 // esp: stack pointer (restored after C call) |
5254 // edi: number of arguments including receiver (C callee-saved) | 5241 // edi: number of arguments including receiver (C callee-saved) |
5255 // esi: pointer to the first argument (C callee-saved) | 5242 // esi: pointer to the first argument (C callee-saved) |
5256 | 5243 |
5257 if (do_gc) { | 5244 if (do_gc) { |
5258 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result. | 5245 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result. |
5259 __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY); | 5246 __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY); |
5260 } | 5247 } |
5261 | 5248 |
5262 // Call C function. | 5249 // Call C function. |
5263 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. | 5250 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. |
5264 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. | 5251 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. |
5265 __ call(Operand(ebx)); | 5252 __ call(Operand(ebx)); |
5266 // Result is in eax or edx:eax - do not destroy these registers! | 5253 // Result is in eax or edx:eax - do not destroy these registers! |
5267 | 5254 |
5268 // Check for failure result. | 5255 // Check for failure result. |
5269 Label failure_returned; | 5256 Label failure_returned; |
5270 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 5257 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
5271 __ lea(ecx, Operand(eax, 1)); | 5258 __ lea(ecx, Operand(eax, 1)); |
5272 // Lower 2 bits of ecx are 0 iff eax has failure tag. | 5259 // Lower 2 bits of ecx are 0 iff eax has failure tag. |
5273 __ test(ecx, Immediate(kFailureTagMask)); | 5260 __ test(ecx, Immediate(kFailureTagMask)); |
5274 __ j(zero, &failure_returned, not_taken); | 5261 __ j(zero, &failure_returned, not_taken); |
5275 | 5262 |
5276 // Restore the memory copy of the registers by digging them out from | 5263 // Exit the JavaScript to C++ exit frame. |
5277 // the stack. | 5264 __ LeaveExitFrame(frame_type); |
5278 if (do_restore) { | |
5279 // Ok to clobber ebx and edi - function pointer and number of arguments not | |
5280 // needed anymore. | |
5281 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | |
5282 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; | |
5283 __ lea(ebx, Operand(ebp, kOffset)); | |
5284 __ CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); | |
5285 } | |
5286 | |
5287 // Exit C frame. | |
5288 __ LeaveExitFrame(); | |
5289 __ ret(0); | 5265 __ ret(0); |
5290 | 5266 |
5291 // Handling of Failure. | 5267 // Handling of failure. |
5292 __ bind(&failure_returned); | 5268 __ bind(&failure_returned); |
5293 | 5269 |
5294 Label retry; | 5270 Label retry; |
5295 // If the returned exception is RETRY_AFTER_GC continue at retry label | 5271 // If the returned exception is RETRY_AFTER_GC continue at retry label |
5296 ASSERT(Failure::RETRY_AFTER_GC == 0); | 5272 ASSERT(Failure::RETRY_AFTER_GC == 0); |
5297 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 5273 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
5298 __ j(zero, &retry, taken); | 5274 __ j(zero, &retry, taken); |
5299 | 5275 |
5300 Label continue_exception; | 5276 Label continue_exception; |
5301 // If the returned failure is EXCEPTION then promote Top::pending_exception(). | 5277 // If the returned failure is EXCEPTION then promote Top::pending_exception(). |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5385 // this by performing a garbage collection and retrying the | 5361 // this by performing a garbage collection and retrying the |
5386 // builtin once. | 5362 // builtin once. |
5387 | 5363 |
5388 StackFrame::Type frame_type = is_debug_break ? | 5364 StackFrame::Type frame_type = is_debug_break ? |
5389 StackFrame::EXIT_DEBUG : | 5365 StackFrame::EXIT_DEBUG : |
5390 StackFrame::EXIT; | 5366 StackFrame::EXIT; |
5391 | 5367 |
5392 // Enter the exit frame that transitions from JavaScript to C++. | 5368 // Enter the exit frame that transitions from JavaScript to C++. |
5393 __ EnterExitFrame(frame_type); | 5369 __ EnterExitFrame(frame_type); |
5394 | 5370 |
5395 if (is_debug_break) { | |
5396 // Save the state of all registers to the stack from the memory | |
5397 // location. | |
5398 | |
5399 // TODO(1243899): This should be symmetric to | |
5400 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed | |
5401 // correct here, but computed for the other call. Very error | |
5402 // prone! FIX THIS. Actually there are deeper problems with | |
5403 // register saving than this asymmetry (see the bug report | |
5404 // associated with this issue). | |
5405 __ PushRegistersFromMemory(kJSCallerSaved); | |
5406 } | |
5407 | |
5408 // Allocate stack space for 2 arguments (argc, argv). | |
5409 GenerateReserveCParameterSpace(masm, 2); | |
5410 __ mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); // save entry sp | |
5411 | |
5412 // eax: result parameter for PerformGC, if any (setup below) | 5371 // eax: result parameter for PerformGC, if any (setup below) |
5413 // ebx: pointer to builtin function (C callee-saved) | 5372 // ebx: pointer to builtin function (C callee-saved) |
5414 // ebp: frame pointer (restored after C call) | 5373 // ebp: frame pointer (restored after C call) |
5415 // esp: stack pointer (restored after C call) | 5374 // esp: stack pointer (restored after C call) |
5416 // edi: number of arguments including receiver (C callee-saved) | 5375 // edi: number of arguments including receiver (C callee-saved) |
5417 | 5376 // esi: argv pointer (C callee-saved) |
5418 Label entry; | |
5419 __ bind(&entry); | |
5420 | 5377 |
5421 Label throw_out_of_memory_exception; | 5378 Label throw_out_of_memory_exception; |
5422 Label throw_normal_exception; | 5379 Label throw_normal_exception; |
5423 | 5380 |
5424 #ifdef DEBUG | 5381 #ifdef DEBUG |
5425 if (FLAG_gc_greedy) { | 5382 if (FLAG_gc_greedy) { |
5426 Failure* failure = Failure::RetryAfterGC(0, NEW_SPACE); | 5383 Failure* failure = Failure::RetryAfterGC(0, NEW_SPACE); |
5427 __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(failure))); | 5384 __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(failure))); |
5428 } | 5385 } |
5429 GenerateCore(masm, &throw_normal_exception, | 5386 GenerateCore(masm, &throw_normal_exception, |
5430 &throw_out_of_memory_exception, | 5387 &throw_out_of_memory_exception, |
5431 FLAG_gc_greedy, | 5388 frame_type, |
5432 is_debug_break); | 5389 FLAG_gc_greedy); |
5433 #else | 5390 #else |
5434 GenerateCore(masm, | 5391 GenerateCore(masm, |
5435 &throw_normal_exception, | 5392 &throw_normal_exception, |
5436 &throw_out_of_memory_exception, | 5393 &throw_out_of_memory_exception, |
5437 false, | 5394 frame_type, |
5438 is_debug_break); | 5395 false); |
5439 #endif | 5396 #endif |
| 5397 |
5440 GenerateCore(masm, | 5398 GenerateCore(masm, |
5441 &throw_normal_exception, | 5399 &throw_normal_exception, |
5442 &throw_out_of_memory_exception, | 5400 &throw_out_of_memory_exception, |
5443 true, | 5401 frame_type, |
5444 is_debug_break); | 5402 true); |
5445 | 5403 |
5446 __ bind(&throw_out_of_memory_exception); | 5404 __ bind(&throw_out_of_memory_exception); |
5447 GenerateThrowOutOfMemory(masm); | 5405 GenerateThrowOutOfMemory(masm); |
5448 // control flow for generated will not return. | 5406 // control flow for generated will not return. |
5449 | 5407 |
5450 __ bind(&throw_normal_exception); | 5408 __ bind(&throw_normal_exception); |
5451 GenerateThrowTOS(masm); | 5409 GenerateThrowTOS(masm); |
5452 } | 5410 } |
5453 | 5411 |
5454 | 5412 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5545 bool is_eval) { | 5503 bool is_eval) { |
5546 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); | 5504 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); |
5547 if (!code.is_null()) { | 5505 if (!code.is_null()) { |
5548 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 5506 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
5549 } | 5507 } |
5550 return code; | 5508 return code; |
5551 } | 5509 } |
5552 | 5510 |
5553 | 5511 |
5554 } } // namespace v8::internal | 5512 } } // namespace v8::internal |
OLD | NEW |