| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 int id = environment->deoptimization_index(); | 925 int id = environment->deoptimization_index(); |
| 926 ASSERT(info()->IsOptimizing() || info()->IsStub()); | 926 ASSERT(info()->IsOptimizing() || info()->IsStub()); |
| 927 Address entry = | 927 Address entry = |
| 928 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 928 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 929 if (entry == NULL) { | 929 if (entry == NULL) { |
| 930 Abort("bailout was not prepared"); | 930 Abort("bailout was not prepared"); |
| 931 return; | 931 return; |
| 932 } | 932 } |
| 933 | 933 |
| 934 if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { | 934 if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { |
| 935 Handle<SharedFunctionInfo> shared(info()->shared_info()); | 935 ExternalReference count = ExternalReference::stress_deopt_count(isolate()); |
| 936 Label no_deopt; | 936 Label no_deopt; |
| 937 __ pushfd(); | 937 __ pushfd(); |
| 938 __ push(eax); | 938 __ push(eax); |
| 939 __ push(ebx); | 939 __ mov(eax, Operand::StaticVariable(count)); |
| 940 __ mov(ebx, shared); | 940 __ sub(eax, Immediate(1)); |
| 941 __ mov(eax, | |
| 942 FieldOperand(ebx, SharedFunctionInfo::kStressDeoptCounterOffset)); | |
| 943 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); | |
| 944 __ j(not_zero, &no_deopt, Label::kNear); | 941 __ j(not_zero, &no_deopt, Label::kNear); |
| 945 if (FLAG_trap_on_deopt) __ int3(); | 942 if (FLAG_trap_on_deopt) __ int3(); |
| 946 __ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times))); | 943 __ mov(eax, Immediate(FLAG_deopt_every_n_times)); |
| 947 __ mov(FieldOperand(ebx, SharedFunctionInfo::kStressDeoptCounterOffset), | 944 __ mov(Operand::StaticVariable(count), eax); |
| 948 eax); | |
| 949 __ pop(ebx); | |
| 950 __ pop(eax); | 945 __ pop(eax); |
| 951 __ popfd(); | 946 __ popfd(); |
| 952 ASSERT(frame_is_built_); | 947 ASSERT(frame_is_built_); |
| 953 __ call(entry, RelocInfo::RUNTIME_ENTRY); | 948 __ call(entry, RelocInfo::RUNTIME_ENTRY); |
| 954 | |
| 955 __ bind(&no_deopt); | 949 __ bind(&no_deopt); |
| 956 __ mov(FieldOperand(ebx, SharedFunctionInfo::kStressDeoptCounterOffset), | 950 __ mov(Operand::StaticVariable(count), eax); |
| 957 eax); | |
| 958 __ pop(ebx); | |
| 959 __ pop(eax); | 951 __ pop(eax); |
| 960 __ popfd(); | 952 __ popfd(); |
| 961 } | 953 } |
| 962 | 954 |
| 963 // Before Instructions which can deopt, we normally flush the x87 stack. But | 955 // Before Instructions which can deopt, we normally flush the x87 stack. But |
| 964 // we can have inputs or outputs of the current instruction on the stack, | 956 // we can have inputs or outputs of the current instruction on the stack, |
| 965 // thus we need to flush them here from the physical stack to leave it in a | 957 // thus we need to flush them here from the physical stack to leave it in a |
| 966 // consistent state. | 958 // consistent state. |
| 967 if (x87_stack_depth_ > 0) { | 959 if (x87_stack_depth_ > 0) { |
| 968 Label done; | 960 Label done; |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 case CodeStub::SubString: { | 1215 case CodeStub::SubString: { |
| 1224 SubStringStub stub; | 1216 SubStringStub stub; |
| 1225 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1217 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1226 break; | 1218 break; |
| 1227 } | 1219 } |
| 1228 case CodeStub::NumberToString: { | 1220 case CodeStub::NumberToString: { |
| 1229 NumberToStringStub stub; | 1221 NumberToStringStub stub; |
| 1230 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1222 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1231 break; | 1223 break; |
| 1232 } | 1224 } |
| 1233 case CodeStub::StringAdd: { | |
| 1234 StringAddStub stub(NO_STRING_ADD_FLAGS); | |
| 1235 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 1236 break; | |
| 1237 } | |
| 1238 case CodeStub::StringCompare: { | 1225 case CodeStub::StringCompare: { |
| 1239 StringCompareStub stub; | 1226 StringCompareStub stub; |
| 1240 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1227 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1241 break; | 1228 break; |
| 1242 } | 1229 } |
| 1243 case CodeStub::TranscendentalCache: { | 1230 case CodeStub::TranscendentalCache: { |
| 1244 TranscendentalCacheStub stub(instr->transcendental_type(), | 1231 TranscendentalCacheStub stub(instr->transcendental_type(), |
| 1245 TranscendentalCacheStub::TAGGED); | 1232 TranscendentalCacheStub::TAGGED); |
| 1246 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1233 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1247 break; | 1234 break; |
| (...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2985 ASSERT(ToRegister(instr->value()).is(eax)); | 2972 ASSERT(ToRegister(instr->value()).is(eax)); |
| 2986 | 2973 |
| 2987 __ mov(ecx, instr->name()); | 2974 __ mov(ecx, instr->name()); |
| 2988 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 2975 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 2989 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2976 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2990 : isolate()->builtins()->StoreIC_Initialize(); | 2977 : isolate()->builtins()->StoreIC_Initialize(); |
| 2991 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2978 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2992 } | 2979 } |
| 2993 | 2980 |
| 2994 | 2981 |
| 2982 void LCodeGen::DoLinkObjectInList(LLinkObjectInList* instr) { |
| 2983 Register object = ToRegister(instr->object()); |
| 2984 Register temp = ToRegister(instr->temp()); |
| 2985 ExternalReference sites_list_address = instr->GetReference(isolate()); |
| 2986 |
| 2987 __ mov(temp, Immediate(sites_list_address)); |
| 2988 __ mov(temp, Operand(temp, 0)); |
| 2989 __ mov(FieldOperand(object, instr->hydrogen()->store_field().offset()), |
| 2990 temp); |
| 2991 __ mov(temp, Immediate(sites_list_address)); |
| 2992 __ mov(Operand(temp, 0), object); |
| 2993 } |
| 2994 |
| 2995 |
| 2995 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2996 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2996 Register context = ToRegister(instr->context()); | 2997 Register context = ToRegister(instr->context()); |
| 2997 Register result = ToRegister(instr->result()); | 2998 Register result = ToRegister(instr->result()); |
| 2998 __ mov(result, ContextOperand(context, instr->slot_index())); | 2999 __ mov(result, ContextOperand(context, instr->slot_index())); |
| 2999 | 3000 |
| 3000 if (instr->hydrogen()->RequiresHoleCheck()) { | 3001 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3001 __ cmp(result, factory()->the_hole_value()); | 3002 __ cmp(result, factory()->the_hole_value()); |
| 3002 if (instr->hydrogen()->DeoptimizesOnHole()) { | 3003 if (instr->hydrogen()->DeoptimizesOnHole()) { |
| 3003 DeoptimizeIf(equal, instr->environment()); | 3004 DeoptimizeIf(equal, instr->environment()); |
| 3004 } else { | 3005 } else { |
| (...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4677 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 4678 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 4678 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 4679 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 4679 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 4680 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 4680 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4681 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4681 } | 4682 } |
| 4682 | 4683 |
| 4683 | 4684 |
| 4684 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4685 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| 4685 Register object = ToRegister(instr->object()); | 4686 Register object = ToRegister(instr->object()); |
| 4686 Register temp = ToRegister(instr->temp()); | 4687 Register temp = ToRegister(instr->temp()); |
| 4687 __ TestJSArrayForAllocationSiteInfo(object, temp); | 4688 __ TestJSArrayForAllocationMemento(object, temp); |
| 4688 DeoptimizeIf(equal, instr->environment()); | 4689 DeoptimizeIf(equal, instr->environment()); |
| 4689 } | 4690 } |
| 4690 | 4691 |
| 4691 | 4692 |
| 4692 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4693 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
| 4693 Register object_reg = ToRegister(instr->object()); | 4694 Register object_reg = ToRegister(instr->object()); |
| 4694 | 4695 |
| 4695 Handle<Map> from_map = instr->original_map(); | 4696 Handle<Map> from_map = instr->original_map(); |
| 4696 Handle<Map> to_map = instr->transitioned_map(); | 4697 Handle<Map> to_map = instr->transitioned_map(); |
| 4697 ElementsKind from_kind = instr->from_kind(); | 4698 ElementsKind from_kind = instr->from_kind(); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4860 void LCodeGen::DoStringLength(LStringLength* instr) { | 4861 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 4861 Register string = ToRegister(instr->string()); | 4862 Register string = ToRegister(instr->string()); |
| 4862 Register result = ToRegister(instr->result()); | 4863 Register result = ToRegister(instr->result()); |
| 4863 __ mov(result, FieldOperand(string, String::kLengthOffset)); | 4864 __ mov(result, FieldOperand(string, String::kLengthOffset)); |
| 4864 } | 4865 } |
| 4865 | 4866 |
| 4866 | 4867 |
| 4867 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4868 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4868 EmitPushTaggedOperand(instr->left()); | 4869 EmitPushTaggedOperand(instr->left()); |
| 4869 EmitPushTaggedOperand(instr->right()); | 4870 EmitPushTaggedOperand(instr->right()); |
| 4870 StringAddStub stub(NO_STRING_CHECK_IN_STUB); | 4871 StringAddStub stub(instr->hydrogen()->flags()); |
| 4871 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4872 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4872 } | 4873 } |
| 4873 | 4874 |
| 4874 | 4875 |
| 4875 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4876 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 4876 if (CpuFeatures::IsSupported(SSE2)) { | 4877 if (CpuFeatures::IsSupported(SSE2)) { |
| 4877 CpuFeatureScope scope(masm(), SSE2); | 4878 CpuFeatureScope scope(masm(), SSE2); |
| 4878 LOperand* input = instr->value(); | 4879 LOperand* input = instr->value(); |
| 4879 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4880 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4880 LOperand* output = instr->result(); | 4881 LOperand* output = instr->result(); |
| (...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6038 | 6039 |
| 6039 if (instr->size()->IsConstantOperand()) { | 6040 if (instr->size()->IsConstantOperand()) { |
| 6040 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 6041 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 6041 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 6042 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); |
| 6042 } else { | 6043 } else { |
| 6043 Register size = ToRegister(instr->size()); | 6044 Register size = ToRegister(instr->size()); |
| 6044 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 6045 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); |
| 6045 } | 6046 } |
| 6046 | 6047 |
| 6047 __ bind(deferred->exit()); | 6048 __ bind(deferred->exit()); |
| 6049 |
| 6050 if (instr->hydrogen()->MustPrefillWithFiller()) { |
| 6051 if (instr->size()->IsConstantOperand()) { |
| 6052 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 6053 __ mov(temp, (size / kPointerSize) - 1); |
| 6054 } else { |
| 6055 temp = ToRegister(instr->size()); |
| 6056 __ shr(temp, kPointerSizeLog2); |
| 6057 __ dec(temp); |
| 6058 } |
| 6059 Label loop; |
| 6060 __ bind(&loop); |
| 6061 __ mov(FieldOperand(result, temp, times_pointer_size, 0), |
| 6062 isolate()->factory()->one_pointer_filler_map()); |
| 6063 __ dec(temp); |
| 6064 __ j(not_zero, &loop); |
| 6065 } |
| 6048 } | 6066 } |
| 6049 | 6067 |
| 6050 | 6068 |
| 6051 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 6069 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
| 6052 Register result = ToRegister(instr->result()); | 6070 Register result = ToRegister(instr->result()); |
| 6053 | 6071 |
| 6054 // TODO(3095996): Get rid of this. For now, we need to make the | 6072 // TODO(3095996): Get rid of this. For now, we need to make the |
| 6055 // result register contain a valid pointer because it is already | 6073 // result register contain a valid pointer because it is already |
| 6056 // contained in the register pointer map. | 6074 // contained in the register pointer map. |
| 6057 __ mov(result, Immediate(Smi::FromInt(0))); | 6075 __ mov(result, Immediate(Smi::FromInt(0))); |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6483 FixedArray::kHeaderSize - kPointerSize)); | 6501 FixedArray::kHeaderSize - kPointerSize)); |
| 6484 __ bind(&done); | 6502 __ bind(&done); |
| 6485 } | 6503 } |
| 6486 | 6504 |
| 6487 | 6505 |
| 6488 #undef __ | 6506 #undef __ |
| 6489 | 6507 |
| 6490 } } // namespace v8::internal | 6508 } } // namespace v8::internal |
| 6491 | 6509 |
| 6492 #endif // V8_TARGET_ARCH_IA32 | 6510 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |