| 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 |