diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-12-07 13:56:11 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-12-07 13:56:11 -0800 |
commit | c30f1137121315b0d3641af6dc61e3b047f940e1 (patch) | |
tree | f118eaf670505e6a63f28bc8df845520f67adc55 /deps/v8/src/ia32/builtins-ia32.cc | |
parent | 5b8c62f7d12c1c5a553e765ba05bbd8a7e17ee47 (diff) | |
download | node-new-c30f1137121315b0d3641af6dc61e3b047f940e1.tar.gz |
Upgrade V8 to 3.0.0
Diffstat (limited to 'deps/v8/src/ia32/builtins-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/builtins-ia32.cc | 153 |
1 files changed, 152 insertions, 1 deletions
diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc index 0ad3e6d48f..c28e144410 100644 --- a/deps/v8/src/ia32/builtins-ia32.cc +++ b/deps/v8/src/ia32/builtins-ia32.cc @@ -1,4 +1,4 @@ -// Copyright 2006-2009 the V8 project authors. All rights reserved. +// Copyright 2010 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -31,6 +31,8 @@ #include "code-stubs.h" #include "codegen-inl.h" +#include "deoptimizer.h" +#include "full-codegen.h" namespace v8 { namespace internal { @@ -480,6 +482,85 @@ void Builtins::Generate_LazyCompile(MacroAssembler* masm) { } +void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { + // Enter an internal frame. + __ EnterInternalFrame(); + + // Push a copy of the function onto the stack. + __ push(edi); + + __ push(edi); // Function is also the parameter to the runtime call. + __ CallRuntime(Runtime::kLazyRecompile, 1); + + // Restore function and tear down temporary frame. + __ pop(edi); + __ LeaveInternalFrame(); + + // Do a tail-call of the compiled function. + __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); + __ jmp(Operand(ecx)); +} + + +static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, + Deoptimizer::BailoutType type) { + // Enter an internal frame. + __ EnterInternalFrame(); + + // Pass the function and deoptimization type to the runtime system. + __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); + __ CallRuntime(Runtime::kNotifyDeoptimized, 1); + + // Tear down temporary frame. + __ LeaveInternalFrame(); + + // Get the full codegen state from the stack and untag it. + __ mov(ecx, Operand(esp, 1 * kPointerSize)); + __ SmiUntag(ecx); + + // Switch on the state. + NearLabel not_no_registers, not_tos_eax; + __ cmp(ecx, FullCodeGenerator::NO_REGISTERS); + __ j(not_equal, ¬_no_registers); + __ ret(1 * kPointerSize); // Remove state. + + __ bind(¬_no_registers); + __ mov(eax, Operand(esp, 2 * kPointerSize)); + __ cmp(ecx, FullCodeGenerator::TOS_REG); + __ j(not_equal, ¬_tos_eax); + __ ret(2 * kPointerSize); // Remove state, eax. + + __ bind(¬_tos_eax); + __ Abort("no cases left"); +} + + +void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { + Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); +} + + +void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { + Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); +} + + +void Builtins::Generate_NotifyOSR(MacroAssembler* masm) { + // TODO(kasperl): Do we need to save/restore the XMM registers too? + + // For now, we are relying on the fact that Runtime::NotifyOSR + // doesn't do any garbage collection which allows us to save/restore + // the registers without worrying about which of them contain + // pointers. This seems a bit fragile. + __ pushad(); + __ EnterInternalFrame(); + __ CallRuntime(Runtime::kNotifyOSR, 0); + __ LeaveInternalFrame(); + __ popad(); + __ ret(0); +} + + void Builtins::Generate_FunctionCall(MacroAssembler* masm) { // 1. Make sure we have at least one argument. { Label done; @@ -1418,6 +1499,76 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { } +void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { + // We shouldn't be performing on-stack replacement in the first + // place if the CPU features we need for the optimized Crankshaft + // code aren't supported. + CpuFeatures::Probe(false); + if (!CpuFeatures::IsSupported(SSE2)) { + __ Abort("Unreachable code: Cannot optimize without SSE2 support."); + return; + } + + // Get the loop depth of the stack guard check. This is recorded in + // a test(eax, depth) instruction right after the call. + Label stack_check; + __ mov(ebx, Operand(esp, 0)); // return address + if (FLAG_debug_code) { + __ cmpb(Operand(ebx, 0), Assembler::kTestAlByte); + __ Assert(equal, "test eax instruction not found after loop stack check"); + } + __ movzx_b(ebx, Operand(ebx, 1)); // depth + + // Get the loop nesting level at which we allow OSR from the + // unoptimized code and check if we want to do OSR yet. If not we + // should perform a stack guard check so we can get interrupts while + // waiting for on-stack replacement. + __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); + __ mov(ecx, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); + __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset)); + __ cmpb(ebx, FieldOperand(ecx, Code::kAllowOSRAtLoopNestingLevelOffset)); + __ j(greater, &stack_check); + + // Pass the function to optimize as the argument to the on-stack + // replacement runtime function. + __ EnterInternalFrame(); + __ push(eax); + __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); + __ LeaveInternalFrame(); + + // If the result was -1 it means that we couldn't optimize the + // function. Just return and continue in the unoptimized version. + NearLabel skip; + __ cmp(Operand(eax), Immediate(Smi::FromInt(-1))); + __ j(not_equal, &skip); + __ ret(0); + + // If we decide not to perform on-stack replacement we perform a + // stack guard check to enable interrupts. + __ bind(&stack_check); + NearLabel ok; + ExternalReference stack_limit = + ExternalReference::address_of_stack_limit(); + __ cmp(esp, Operand::StaticVariable(stack_limit)); + __ j(above_equal, &ok, taken); + StackCheckStub stub; + __ TailCallStub(&stub); + __ Abort("Unreachable code: returned from tail call."); + __ bind(&ok); + __ ret(0); + + __ bind(&skip); + // Untag the AST id and push it on the stack. + __ SmiUntag(eax); + __ push(eax); + + // Generate the code for doing the frame-to-frame translation using + // the deoptimizer infrastructure. + Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); + generator.Generate(); +} + + #undef __ } } // namespace v8::internal |