| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 | 
| 6 | 6 | 
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" | 
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" | 
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" | 
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" | 
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 845   // This simulates the initial call to bytecode handlers in interpreter entry | 845   // This simulates the initial call to bytecode handlers in interpreter entry | 
| 846   // trampoline. The return will never actually be taken, but our stack walker | 846   // trampoline. The return will never actually be taken, but our stack walker | 
| 847   // uses this address to determine whether a frame is interpreted. | 847   // uses this address to determine whether a frame is interpreted. | 
| 848   __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); | 848   __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); | 
| 849 | 849 | 
| 850   Generate_EnterBytecodeDispatch(masm); | 850   Generate_EnterBytecodeDispatch(masm); | 
| 851 } | 851 } | 
| 852 | 852 | 
| 853 | 853 | 
| 854 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 854 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 
| 855   // ----------- S t a t e ------------- |  | 
| 856   //  -- edx : new target (preserved for callee) |  | 
| 857   //  -- edi : target function (preserved for callee) |  | 
| 858   // ----------------------------------- |  | 
| 859   // First lookup code, maybe we don't need to compile! |  | 
| 860   Label gotta_call_runtime, gotta_call_runtime_no_stack; |  | 
| 861   Label maybe_call_runtime; |  | 
| 862   Label try_shared; |  | 
| 863   Label loop_top, loop_bottom; |  | 
| 864 |  | 
| 865   Register closure = edi; |  | 
| 866   Register new_target = edx; |  | 
| 867   __ push(new_target); |  | 
| 868   __ push(closure); |  | 
| 869 |  | 
| 870   Register map = eax; |  | 
| 871   Register index = ebx; |  | 
| 872   __ mov(map, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset)); |  | 
| 873   __ mov(map, FieldOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset)); |  | 
| 874   __ mov(index, FieldOperand(map, FixedArray::kLengthOffset)); |  | 
| 875   __ cmp(index, Immediate(Smi::FromInt(2))); |  | 
| 876   __ j(less, &gotta_call_runtime); |  | 
| 877 |  | 
| 878   // Find literals. |  | 
| 879   // edx : native context |  | 
| 880   // ebx : length / index |  | 
| 881   // eax : optimized code map |  | 
| 882   // stack[0] : new target |  | 
| 883   // stack[4] : closure |  | 
| 884   Register native_context = edx; |  | 
| 885   __ mov(native_context, NativeContextOperand()); |  | 
| 886 |  | 
| 887   __ bind(&loop_top); |  | 
| 888   Register temp = edi; |  | 
| 889 |  | 
| 890   // Does the native context match? |  | 
| 891   __ mov(temp, FieldOperand(map, index, times_half_pointer_size, |  | 
| 892                             SharedFunctionInfo::OffsetToPreviousContext())); |  | 
| 893   __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset)); |  | 
| 894   __ cmp(temp, native_context); |  | 
| 895   __ j(not_equal, &loop_bottom); |  | 
| 896   // OSR id set to none? |  | 
| 897   __ mov(temp, FieldOperand(map, index, times_half_pointer_size, |  | 
| 898                             SharedFunctionInfo::OffsetToPreviousOsrAstId())); |  | 
| 899   const int bailout_id = BailoutId::None().ToInt(); |  | 
| 900   __ cmp(temp, Immediate(Smi::FromInt(bailout_id))); |  | 
| 901   __ j(not_equal, &loop_bottom); |  | 
| 902   // Literals available? |  | 
| 903   __ mov(temp, FieldOperand(map, index, times_half_pointer_size, |  | 
| 904                             SharedFunctionInfo::OffsetToPreviousLiterals())); |  | 
| 905   __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset)); |  | 
| 906   __ JumpIfSmi(temp, &gotta_call_runtime); |  | 
| 907 |  | 
| 908   // Save the literals in the closure. |  | 
| 909   __ mov(ecx, Operand(esp, 0)); |  | 
| 910   __ mov(FieldOperand(ecx, JSFunction::kLiteralsOffset), temp); |  | 
| 911   __ push(index); |  | 
| 912   __ RecordWriteField(ecx, JSFunction::kLiteralsOffset, temp, index, |  | 
| 913                       kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |  | 
| 914   __ pop(index); |  | 
| 915 |  | 
| 916   // Code available? |  | 
| 917   Register entry = ecx; |  | 
| 918   __ mov(entry, FieldOperand(map, index, times_half_pointer_size, |  | 
| 919                              SharedFunctionInfo::OffsetToPreviousCachedCode())); |  | 
| 920   __ mov(entry, FieldOperand(entry, WeakCell::kValueOffset)); |  | 
| 921   __ JumpIfSmi(entry, &maybe_call_runtime); |  | 
| 922 |  | 
| 923   // Found literals and code. Get them into the closure and return. |  | 
| 924   __ pop(closure); |  | 
| 925   // Store code entry in the closure. |  | 
| 926   __ lea(entry, FieldOperand(entry, Code::kHeaderSize)); |  | 
| 927 |  | 
| 928   Label install_optimized_code_and_tailcall; |  | 
| 929   __ bind(&install_optimized_code_and_tailcall); |  | 
| 930   __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry); |  | 
| 931   __ RecordWriteCodeEntryField(closure, entry, eax); |  | 
| 932 |  | 
| 933   // Link the closure into the optimized function list. |  | 
| 934   // ecx : code entry |  | 
| 935   // edx : native context |  | 
| 936   // edi : closure |  | 
| 937   __ mov(ebx, |  | 
| 938          ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST)); |  | 
| 939   __ mov(FieldOperand(closure, JSFunction::kNextFunctionLinkOffset), ebx); |  | 
| 940   __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, ebx, eax, |  | 
| 941                       kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |  | 
| 942   const int function_list_offset = |  | 
| 943       Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST); |  | 
| 944   __ mov(ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST), |  | 
| 945          closure); |  | 
| 946   // Save closure before the write barrier. |  | 
| 947   __ mov(ebx, closure); |  | 
| 948   __ RecordWriteContextSlot(native_context, function_list_offset, closure, eax, |  | 
| 949                             kDontSaveFPRegs); |  | 
| 950   __ mov(closure, ebx); |  | 
| 951   __ pop(new_target); |  | 
| 952   __ jmp(entry); |  | 
| 953 |  | 
| 954   __ bind(&loop_bottom); |  | 
| 955   __ sub(index, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength))); |  | 
| 956   __ cmp(index, Immediate(Smi::FromInt(1))); |  | 
| 957   __ j(greater, &loop_top); |  | 
| 958 |  | 
| 959   // We found neither literals nor code. |  | 
| 960   __ jmp(&gotta_call_runtime); |  | 
| 961 |  | 
| 962   __ bind(&maybe_call_runtime); |  | 
| 963   __ pop(closure); |  | 
| 964 |  | 
| 965   // Last possibility. Check the context free optimized code map entry. |  | 
| 966   __ mov(entry, FieldOperand(map, FixedArray::kHeaderSize + |  | 
| 967                                       SharedFunctionInfo::kSharedCodeIndex)); |  | 
| 968   __ mov(entry, FieldOperand(entry, WeakCell::kValueOffset)); |  | 
| 969   __ JumpIfSmi(entry, &try_shared); |  | 
| 970 |  | 
| 971   // Store code entry in the closure. |  | 
| 972   __ lea(entry, FieldOperand(entry, Code::kHeaderSize)); |  | 
| 973   __ jmp(&install_optimized_code_and_tailcall); |  | 
| 974 |  | 
| 975   __ bind(&try_shared); |  | 
| 976   __ pop(new_target); |  | 
| 977   // Is the full code valid? |  | 
| 978   __ mov(entry, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset)); |  | 
| 979   __ mov(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset)); |  | 
| 980   __ mov(ebx, FieldOperand(entry, Code::kFlagsOffset)); |  | 
| 981   __ and_(ebx, Code::KindField::kMask); |  | 
| 982   __ shr(ebx, Code::KindField::kShift); |  | 
| 983   __ cmp(ebx, Immediate(Code::BUILTIN)); |  | 
| 984   __ j(equal, &gotta_call_runtime_no_stack); |  | 
| 985   // Yes, install the full code. |  | 
| 986   __ lea(entry, FieldOperand(entry, Code::kHeaderSize)); |  | 
| 987   __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry); |  | 
| 988   __ RecordWriteCodeEntryField(closure, entry, eax); |  | 
| 989   __ jmp(entry); |  | 
| 990 |  | 
| 991   __ bind(&gotta_call_runtime); |  | 
| 992   __ pop(closure); |  | 
| 993   __ pop(new_target); |  | 
| 994   __ bind(&gotta_call_runtime_no_stack); |  | 
| 995   CallRuntimePassFunction(masm, Runtime::kCompileLazy); | 855   CallRuntimePassFunction(masm, Runtime::kCompileLazy); | 
| 996   GenerateTailCallToReturnedCode(masm); | 856   GenerateTailCallToReturnedCode(masm); | 
| 997 } | 857 } | 
| 998 | 858 | 
| 999 | 859 | 
| 1000 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 860 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 
| 1001   CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent); | 861   CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent); | 
| 1002   GenerateTailCallToReturnedCode(masm); | 862   GenerateTailCallToReturnedCode(masm); | 
| 1003 } | 863 } | 
| 1004 | 864 | 
| (...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2943 | 2803 | 
| 2944   __ bind(&ok); | 2804   __ bind(&ok); | 
| 2945   __ ret(0); | 2805   __ ret(0); | 
| 2946 } | 2806 } | 
| 2947 | 2807 | 
| 2948 #undef __ | 2808 #undef __ | 
| 2949 }  // namespace internal | 2809 }  // namespace internal | 
| 2950 }  // namespace v8 | 2810 }  // namespace v8 | 
| 2951 | 2811 | 
| 2952 #endif  // V8_TARGET_ARCH_X87 | 2812 #endif  // V8_TARGET_ARCH_X87 | 
| OLD | NEW | 
|---|