Chromium Code Reviews| 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 5240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5251 // ebp: frame pointer (restored after C call) | 5251 // ebp: frame pointer (restored after C call) |
| 5252 // esp: stack pointer (restored after C call) | 5252 // esp: stack pointer (restored after C call) |
| 5253 // edi: number of arguments including receiver (C callee-saved) | 5253 // edi: number of arguments including receiver (C callee-saved) |
| 5254 | 5254 |
| 5255 if (do_gc) { | 5255 if (do_gc) { |
| 5256 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result. | 5256 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result. |
| 5257 __ call(FUNCTION_ADDR(Runtime::PerformGC), runtime_entry); | 5257 __ call(FUNCTION_ADDR(Runtime::PerformGC), runtime_entry); |
| 5258 } | 5258 } |
| 5259 | 5259 |
| 5260 // Call C function. | 5260 // Call C function. |
| 5261 __ lea(eax, Operand(ebp, | |
| 5262 edi, | |
| 5263 times_4, | |
| 5264 StandardFrameConstants::kCallerSPOffset - kPointerSize)); | |
| 5265 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. | 5261 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. |
| 5266 __ mov(Operand(esp, 1 * kPointerSize), eax); // argv. | 5262 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. |
|
iposva
2008/09/23 07:51:28
Please add the definition of esi to the contract a
| |
| 5267 __ call(Operand(ebx)); | 5263 __ call(Operand(ebx)); |
| 5268 // Result is in eax or edx:eax - do not destroy these registers! | 5264 // Result is in eax or edx:eax - do not destroy these registers! |
| 5269 | 5265 |
| 5270 // Check for failure result. | 5266 // Check for failure result. |
| 5271 Label failure_returned; | 5267 Label failure_returned; |
| 5272 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 5268 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
| 5273 __ lea(ecx, Operand(eax, 1)); | 5269 __ lea(ecx, Operand(eax, 1)); |
| 5274 // Lower 2 bits of ecx are 0 iff eax has failure tag. | 5270 // Lower 2 bits of ecx are 0 iff eax has failure tag. |
| 5275 __ test(ecx, Immediate(kFailureTagMask)); | 5271 __ test(ecx, Immediate(kFailureTagMask)); |
| 5276 __ j(zero, &failure_returned, not_taken); | 5272 __ j(zero, &failure_returned, not_taken); |
| 5277 | 5273 |
| 5278 // Restore number of arguments to ecx and clear top frame. | |
| 5279 __ mov(ecx, Operand(edi)); | |
| 5280 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | |
| 5281 __ mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | |
| 5282 | |
| 5283 // Restore the memory copy of the registers by digging them out from | 5274 // Restore the memory copy of the registers by digging them out from |
| 5284 // the stack. | 5275 // the stack. |
| 5285 if (do_restore) { | 5276 if (do_restore) { |
| 5286 // Ok to clobber ebx and edi - function pointer and number of arguments not | 5277 // Ok to clobber ebx and edi - function pointer and number of arguments not |
| 5287 // needed anymore. | 5278 // needed anymore. |
| 5288 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | 5279 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; |
| 5289 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; | 5280 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; |
| 5290 __ lea(ebx, Operand(ebp, kOffset)); | 5281 __ lea(ebx, Operand(ebp, kOffset)); |
| 5291 __ CopyRegistersFromStackToMemory(ebx, edi, kJSCallerSaved); | 5282 __ CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); |
| 5292 } | 5283 } |
| 5293 | 5284 |
| 5294 // Exit C frame. | 5285 // Exit C frame. |
| 5295 __ lea(esp, Operand(ebp, -1 * kPointerSize)); | 5286 __ LeaveExitFrame(); |
| 5296 __ pop(ebx); | |
| 5297 __ pop(ebp); | |
| 5298 | |
| 5299 // Restore current context from top and clear it in debug mode. | |
| 5300 ExternalReference context_address(Top::k_context_address); | |
| 5301 __ mov(esi, Operand::StaticVariable(context_address)); | |
| 5302 if (kDebug) { | |
| 5303 __ mov(Operand::StaticVariable(context_address), Immediate(0)); | |
| 5304 } | |
| 5305 | |
| 5306 // Pop arguments from caller's stack and return. | |
| 5307 __ pop(ebx); // Ok to clobber ebx - function pointer not needed anymore. | |
| 5308 __ lea(esp, Operand(esp, ecx, times_4, 0)); | |
| 5309 __ push(ebx); | |
| 5310 __ ret(0); | 5287 __ ret(0); |
| 5311 | 5288 |
| 5312 // Handling of Failure. | 5289 // Handling of Failure. |
| 5313 __ bind(&failure_returned); | 5290 __ bind(&failure_returned); |
| 5314 | 5291 |
| 5315 Label retry; | 5292 Label retry; |
| 5316 // If the returned exception is RETRY_AFTER_GC continue at retry label | 5293 // If the returned exception is RETRY_AFTER_GC continue at retry label |
| 5317 ASSERT(Failure::RETRY_AFTER_GC == 0); | 5294 ASSERT(Failure::RETRY_AFTER_GC == 0); |
| 5318 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 5295 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
| 5319 __ j(zero, &retry, taken); | 5296 __ j(zero, &retry, taken); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5399 // ebp: frame pointer (restored after C call) | 5376 // ebp: frame pointer (restored after C call) |
| 5400 // esp: stack pointer (restored after C call) | 5377 // esp: stack pointer (restored after C call) |
| 5401 // esi: current context (C callee-saved) | 5378 // esi: current context (C callee-saved) |
| 5402 // edi: caller's parameter pointer pp (C callee-saved) | 5379 // edi: caller's parameter pointer pp (C callee-saved) |
| 5403 | 5380 |
| 5404 // NOTE: Invocations of builtins may return failure objects | 5381 // NOTE: Invocations of builtins may return failure objects |
| 5405 // instead of a proper result. The builtin entry handles | 5382 // instead of a proper result. The builtin entry handles |
| 5406 // this by performing a garbage collection and retrying the | 5383 // this by performing a garbage collection and retrying the |
| 5407 // builtin once. | 5384 // builtin once. |
| 5408 | 5385 |
| 5409 // Enter C frame. | 5386 StackFrame::Type frame_type = is_debug_break ? |
| 5410 // Here we make the following assumptions and use them when setting | 5387 StackFrame::EXIT_DEBUG : |
| 5411 // up the top-most Frame. Adjust the code if these assumptions | 5388 StackFrame::EXIT; |
| 5412 // change. | |
| 5413 ASSERT(ExitFrameConstants::kPPDisplacement == +2 * kPointerSize); | |
| 5414 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); | |
| 5415 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | |
| 5416 ASSERT(ExitFrameConstants::kSPOffset == -2 * kPointerSize); | |
| 5417 __ push(ebp); // caller fp | |
| 5418 __ mov(ebp, Operand(esp)); // C entry fp | |
| 5419 __ push(ebx); // C function | |
| 5420 __ push(Immediate(0)); // saved entry sp, set before call | |
| 5421 __ push(Immediate(is_debug_break ? 1 : 0)); | |
| 5422 | 5389 |
| 5423 // Remember top frame. | 5390 // Enter the exit frame that transitions from JavaScript to C++. |
| 5424 ExternalReference c_entry_fp(Top::k_c_entry_fp_address); | 5391 __ EnterExitFrame(frame_type); |
| 5425 ExternalReference context_address(Top::k_context_address); | |
| 5426 __ mov(Operand::StaticVariable(c_entry_fp), ebp); | |
| 5427 __ mov(Operand::StaticVariable(context_address), esi); | |
| 5428 | 5392 |
| 5429 if (is_debug_break) { | 5393 if (is_debug_break) { |
| 5430 // Save the state of all registers to the stack from the memory | 5394 // Save the state of all registers to the stack from the memory |
| 5431 // location. | 5395 // location. |
| 5432 | 5396 |
| 5433 // TODO(1243899): This should be symmetric to | 5397 // TODO(1243899): This should be symmetric to |
| 5434 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed | 5398 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed |
| 5435 // correct here, but computed for the other call. Very error | 5399 // correct here, but computed for the other call. Very error |
| 5436 // prone! FIX THIS. Actually there are deeper problems with | 5400 // prone! FIX THIS. Actually there are deeper problems with |
| 5437 // register saving than this asymmetry (see the bug report | 5401 // register saving than this asymmetry (see the bug report |
| 5438 // associated with this issue). | 5402 // associated with this issue). |
| 5439 __ PushRegistersFromMemory(kJSCallerSaved); | 5403 __ PushRegistersFromMemory(kJSCallerSaved); |
| 5440 } | 5404 } |
| 5441 | 5405 |
| 5442 // Move number of arguments (argc) into callee-saved register. Note | |
| 5443 // that edi is only available after remembering the top frame. | |
| 5444 __ mov(edi, Operand(eax)); | |
| 5445 | |
| 5446 // Allocate stack space for 2 arguments (argc, argv). | 5406 // Allocate stack space for 2 arguments (argc, argv). |
| 5447 GenerateReserveCParameterSpace(masm, 2); | 5407 GenerateReserveCParameterSpace(masm, 2); |
| 5448 __ mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); // save entry sp | 5408 __ mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); // save entry sp |
| 5449 | 5409 |
| 5450 // eax: result parameter for PerformGC, if any (setup below) | 5410 // eax: result parameter for PerformGC, if any (setup below) |
| 5451 // ebx: pointer to builtin function (C callee-saved) | 5411 // ebx: pointer to builtin function (C callee-saved) |
| 5452 // ebp: frame pointer (restored after C call) | 5412 // ebp: frame pointer (restored after C call) |
| 5453 // esp: stack pointer (restored after C call) | 5413 // esp: stack pointer (restored after C call) |
| 5454 // edi: number of arguments including receiver (C callee-saved) | 5414 // edi: number of arguments including receiver (C callee-saved) |
| 5455 | 5415 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5583 bool is_eval) { | 5543 bool is_eval) { |
| 5584 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); | 5544 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); |
| 5585 if (!code.is_null()) { | 5545 if (!code.is_null()) { |
| 5586 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 5546 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
| 5587 } | 5547 } |
| 5588 return code; | 5548 return code; |
| 5589 } | 5549 } |
| 5590 | 5550 |
| 5591 | 5551 |
| 5592 } } // namespace v8::internal | 5552 } } // namespace v8::internal |
| OLD | NEW |