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 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 // Nothing to do. | 1344 // Nothing to do. |
1345 } | 1345 } |
1346 | 1346 |
1347 | 1347 |
1348 void LCodeGen::DoCallStub(LCallStub* instr) { | 1348 void LCodeGen::DoCallStub(LCallStub* instr) { |
1349 ASSERT(ToRegister(instr->context()).is(esi)); | 1349 ASSERT(ToRegister(instr->context()).is(esi)); |
1350 ASSERT(ToRegister(instr->result()).is(eax)); | 1350 ASSERT(ToRegister(instr->result()).is(eax)); |
1351 switch (instr->hydrogen()->major_key()) { | 1351 switch (instr->hydrogen()->major_key()) { |
1352 case CodeStub::RegExpExec: { | 1352 case CodeStub::RegExpExec: { |
1353 RegExpExecStub stub(isolate()); | 1353 RegExpExecStub stub(isolate()); |
1354 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1354 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1355 break; | 1355 break; |
1356 } | 1356 } |
1357 case CodeStub::SubString: { | 1357 case CodeStub::SubString: { |
1358 SubStringStub stub(isolate()); | 1358 SubStringStub stub(isolate()); |
1359 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1359 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1360 break; | 1360 break; |
1361 } | 1361 } |
1362 case CodeStub::StringCompare: { | 1362 case CodeStub::StringCompare: { |
1363 StringCompareStub stub(isolate()); | 1363 StringCompareStub stub(isolate()); |
1364 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1364 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1365 break; | 1365 break; |
1366 } | 1366 } |
1367 default: | 1367 default: |
1368 UNREACHABLE(); | 1368 UNREACHABLE(); |
1369 } | 1369 } |
1370 } | 1370 } |
1371 | 1371 |
1372 | 1372 |
1373 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 1373 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
1374 GenerateOsrPrologue(); | 1374 GenerateOsrPrologue(); |
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2351 } | 2351 } |
2352 | 2352 |
2353 | 2353 |
2354 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 2354 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
2355 ASSERT(ToRegister(instr->context()).is(esi)); | 2355 ASSERT(ToRegister(instr->context()).is(esi)); |
2356 ASSERT(ToRegister(instr->left()).is(edx)); | 2356 ASSERT(ToRegister(instr->left()).is(edx)); |
2357 ASSERT(ToRegister(instr->right()).is(eax)); | 2357 ASSERT(ToRegister(instr->right()).is(eax)); |
2358 ASSERT(ToRegister(instr->result()).is(eax)); | 2358 ASSERT(ToRegister(instr->result()).is(eax)); |
2359 | 2359 |
2360 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 2360 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
2361 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2361 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2362 } | 2362 } |
2363 | 2363 |
2364 | 2364 |
2365 template<class InstrType> | 2365 template<class InstrType> |
2366 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { | 2366 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { |
2367 int left_block = instr->TrueDestination(chunk_); | 2367 int left_block = instr->TrueDestination(chunk_); |
2368 int right_block = instr->FalseDestination(chunk_); | 2368 int right_block = instr->FalseDestination(chunk_); |
2369 | 2369 |
2370 int next_block = GetNextEmittedBlock(); | 2370 int next_block = GetNextEmittedBlock(); |
2371 | 2371 |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2969 Register reg = ToRegister(instr->value()); | 2969 Register reg = ToRegister(instr->value()); |
2970 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); | 2970 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); |
2971 EmitBranch(instr, equal); | 2971 EmitBranch(instr, equal); |
2972 } | 2972 } |
2973 | 2973 |
2974 | 2974 |
2975 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2975 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
2976 // Object and function are in fixed registers defined by the stub. | 2976 // Object and function are in fixed registers defined by the stub. |
2977 ASSERT(ToRegister(instr->context()).is(esi)); | 2977 ASSERT(ToRegister(instr->context()).is(esi)); |
2978 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); | 2978 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); |
2979 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2979 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2980 | 2980 |
2981 Label true_value, done; | 2981 Label true_value, done; |
2982 __ test(eax, Operand(eax)); | 2982 __ test(eax, Operand(eax)); |
2983 __ j(zero, &true_value, Label::kNear); | 2983 __ j(zero, &true_value, Label::kNear); |
2984 __ mov(ToRegister(instr->result()), factory()->false_value()); | 2984 __ mov(ToRegister(instr->result()), factory()->false_value()); |
2985 __ jmp(&done, Label::kNear); | 2985 __ jmp(&done, Label::kNear); |
2986 __ bind(&true_value); | 2986 __ bind(&true_value); |
2987 __ mov(ToRegister(instr->result()), factory()->true_value()); | 2987 __ mov(ToRegister(instr->result()), factory()->true_value()); |
2988 __ bind(&done); | 2988 __ bind(&done); |
2989 } | 2989 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3070 // register which is pushed last by PushSafepointRegisters as top of the | 3070 // register which is pushed last by PushSafepointRegisters as top of the |
3071 // stack is used to pass the offset to the location of the map check to | 3071 // stack is used to pass the offset to the location of the map check to |
3072 // the stub. | 3072 // the stub. |
3073 Register temp = ToRegister(instr->temp()); | 3073 Register temp = ToRegister(instr->temp()); |
3074 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); | 3074 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); |
3075 __ LoadHeapObject(InstanceofStub::right(), instr->function()); | 3075 __ LoadHeapObject(InstanceofStub::right(), instr->function()); |
3076 static const int kAdditionalDelta = 13; | 3076 static const int kAdditionalDelta = 13; |
3077 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 3077 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
3078 __ mov(temp, Immediate(delta)); | 3078 __ mov(temp, Immediate(delta)); |
3079 __ StoreToSafepointRegisterSlot(temp, temp); | 3079 __ StoreToSafepointRegisterSlot(temp, temp); |
3080 CallCodeGeneric(stub.GetCode(isolate()), | 3080 CallCodeGeneric(stub.GetCode(), |
3081 RelocInfo::CODE_TARGET, | 3081 RelocInfo::CODE_TARGET, |
3082 instr, | 3082 instr, |
3083 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 3083 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
3084 // Get the deoptimization index of the LLazyBailout-environment that | 3084 // Get the deoptimization index of the LLazyBailout-environment that |
3085 // corresponds to this instruction. | 3085 // corresponds to this instruction. |
3086 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 3086 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
3087 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 3087 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
3088 | 3088 |
3089 // Put the result value into the eax slot and restore all registers. | 3089 // Put the result value into the eax slot and restore all registers. |
3090 __ StoreToSafepointRegisterSlot(eax, eax); | 3090 __ StoreToSafepointRegisterSlot(eax, eax); |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4269 } | 4269 } |
4270 | 4270 |
4271 | 4271 |
4272 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 4272 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
4273 ASSERT(ToRegister(instr->context()).is(esi)); | 4273 ASSERT(ToRegister(instr->context()).is(esi)); |
4274 ASSERT(ToRegister(instr->function()).is(edi)); | 4274 ASSERT(ToRegister(instr->function()).is(edi)); |
4275 ASSERT(ToRegister(instr->result()).is(eax)); | 4275 ASSERT(ToRegister(instr->result()).is(eax)); |
4276 | 4276 |
4277 int arity = instr->arity(); | 4277 int arity = instr->arity(); |
4278 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); | 4278 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); |
4279 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4279 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4280 } | 4280 } |
4281 | 4281 |
4282 | 4282 |
4283 void LCodeGen::DoCallNew(LCallNew* instr) { | 4283 void LCodeGen::DoCallNew(LCallNew* instr) { |
4284 ASSERT(ToRegister(instr->context()).is(esi)); | 4284 ASSERT(ToRegister(instr->context()).is(esi)); |
4285 ASSERT(ToRegister(instr->constructor()).is(edi)); | 4285 ASSERT(ToRegister(instr->constructor()).is(edi)); |
4286 ASSERT(ToRegister(instr->result()).is(eax)); | 4286 ASSERT(ToRegister(instr->result()).is(eax)); |
4287 | 4287 |
4288 // No cell in ebx for construct type feedback in optimized code | 4288 // No cell in ebx for construct type feedback in optimized code |
4289 __ mov(ebx, isolate()->factory()->undefined_value()); | 4289 __ mov(ebx, isolate()->factory()->undefined_value()); |
4290 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); | 4290 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); |
4291 __ Move(eax, Immediate(instr->arity())); | 4291 __ Move(eax, Immediate(instr->arity())); |
4292 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4292 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4293 } | 4293 } |
4294 | 4294 |
4295 | 4295 |
4296 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 4296 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
4297 ASSERT(ToRegister(instr->context()).is(esi)); | 4297 ASSERT(ToRegister(instr->context()).is(esi)); |
4298 ASSERT(ToRegister(instr->constructor()).is(edi)); | 4298 ASSERT(ToRegister(instr->constructor()).is(edi)); |
4299 ASSERT(ToRegister(instr->result()).is(eax)); | 4299 ASSERT(ToRegister(instr->result()).is(eax)); |
4300 | 4300 |
4301 __ Move(eax, Immediate(instr->arity())); | 4301 __ Move(eax, Immediate(instr->arity())); |
4302 __ mov(ebx, isolate()->factory()->undefined_value()); | 4302 __ mov(ebx, isolate()->factory()->undefined_value()); |
4303 ElementsKind kind = instr->hydrogen()->elements_kind(); | 4303 ElementsKind kind = instr->hydrogen()->elements_kind(); |
4304 AllocationSiteOverrideMode override_mode = | 4304 AllocationSiteOverrideMode override_mode = |
4305 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 4305 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
4306 ? DISABLE_ALLOCATION_SITES | 4306 ? DISABLE_ALLOCATION_SITES |
4307 : DONT_OVERRIDE; | 4307 : DONT_OVERRIDE; |
4308 | 4308 |
4309 if (instr->arity() == 0) { | 4309 if (instr->arity() == 0) { |
4310 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); | 4310 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); |
4311 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4311 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4312 } else if (instr->arity() == 1) { | 4312 } else if (instr->arity() == 1) { |
4313 Label done; | 4313 Label done; |
4314 if (IsFastPackedElementsKind(kind)) { | 4314 if (IsFastPackedElementsKind(kind)) { |
4315 Label packed_case; | 4315 Label packed_case; |
4316 // We might need a change here | 4316 // We might need a change here |
4317 // look at the first argument | 4317 // look at the first argument |
4318 __ mov(ecx, Operand(esp, 0)); | 4318 __ mov(ecx, Operand(esp, 0)); |
4319 __ test(ecx, ecx); | 4319 __ test(ecx, ecx); |
4320 __ j(zero, &packed_case, Label::kNear); | 4320 __ j(zero, &packed_case, Label::kNear); |
4321 | 4321 |
4322 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 4322 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
4323 ArraySingleArgumentConstructorStub stub(isolate(), | 4323 ArraySingleArgumentConstructorStub stub(isolate(), |
4324 holey_kind, | 4324 holey_kind, |
4325 override_mode); | 4325 override_mode); |
4326 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4326 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4327 __ jmp(&done, Label::kNear); | 4327 __ jmp(&done, Label::kNear); |
4328 __ bind(&packed_case); | 4328 __ bind(&packed_case); |
4329 } | 4329 } |
4330 | 4330 |
4331 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); | 4331 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); |
4332 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4332 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4333 __ bind(&done); | 4333 __ bind(&done); |
4334 } else { | 4334 } else { |
4335 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); | 4335 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); |
4336 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4336 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4337 } | 4337 } |
4338 } | 4338 } |
4339 | 4339 |
4340 | 4340 |
4341 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4341 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
4342 ASSERT(ToRegister(instr->context()).is(esi)); | 4342 ASSERT(ToRegister(instr->context()).is(esi)); |
4343 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); | 4343 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); |
4344 } | 4344 } |
4345 | 4345 |
4346 | 4346 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4905 } | 4905 } |
4906 | 4906 |
4907 | 4907 |
4908 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4908 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
4909 ASSERT(ToRegister(instr->context()).is(esi)); | 4909 ASSERT(ToRegister(instr->context()).is(esi)); |
4910 ASSERT(ToRegister(instr->left()).is(edx)); | 4910 ASSERT(ToRegister(instr->left()).is(edx)); |
4911 ASSERT(ToRegister(instr->right()).is(eax)); | 4911 ASSERT(ToRegister(instr->right()).is(eax)); |
4912 StringAddStub stub(isolate(), | 4912 StringAddStub stub(isolate(), |
4913 instr->hydrogen()->flags(), | 4913 instr->hydrogen()->flags(), |
4914 instr->hydrogen()->pretenure_flag()); | 4914 instr->hydrogen()->pretenure_flag()); |
4915 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4915 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4916 } | 4916 } |
4917 | 4917 |
4918 | 4918 |
4919 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4919 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
4920 LOperand* input = instr->value(); | 4920 LOperand* input = instr->value(); |
4921 LOperand* output = instr->result(); | 4921 LOperand* output = instr->result(); |
4922 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4922 ASSERT(input->IsRegister() || input->IsStackSlot()); |
4923 ASSERT(output->IsDoubleRegister()); | 4923 ASSERT(output->IsDoubleRegister()); |
4924 if (CpuFeatures::IsSupported(SSE2)) { | 4924 if (CpuFeatures::IsSupported(SSE2)) { |
4925 CpuFeatureScope scope(masm(), SSE2); | 4925 CpuFeatureScope scope(masm(), SSE2); |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6043 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 6043 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
6044 ASSERT(ToRegister(instr->context()).is(esi)); | 6044 ASSERT(ToRegister(instr->context()).is(esi)); |
6045 // Use the fast case closure allocation code that allocates in new | 6045 // Use the fast case closure allocation code that allocates in new |
6046 // space for nested functions that don't need literals cloning. | 6046 // space for nested functions that don't need literals cloning. |
6047 bool pretenure = instr->hydrogen()->pretenure(); | 6047 bool pretenure = instr->hydrogen()->pretenure(); |
6048 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 6048 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
6049 FastNewClosureStub stub(isolate(), | 6049 FastNewClosureStub stub(isolate(), |
6050 instr->hydrogen()->strict_mode(), | 6050 instr->hydrogen()->strict_mode(), |
6051 instr->hydrogen()->is_generator()); | 6051 instr->hydrogen()->is_generator()); |
6052 __ mov(ebx, Immediate(instr->hydrogen()->shared_info())); | 6052 __ mov(ebx, Immediate(instr->hydrogen()->shared_info())); |
6053 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 6053 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
6054 } else { | 6054 } else { |
6055 __ push(esi); | 6055 __ push(esi); |
6056 __ push(Immediate(instr->hydrogen()->shared_info())); | 6056 __ push(Immediate(instr->hydrogen()->shared_info())); |
6057 __ push(Immediate(pretenure ? factory()->true_value() | 6057 __ push(Immediate(pretenure ? factory()->true_value() |
6058 : factory()->false_value())); | 6058 : factory()->false_value())); |
6059 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); | 6059 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
6060 } | 6060 } |
6061 } | 6061 } |
6062 | 6062 |
6063 | 6063 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6446 __ bind(deferred->exit()); | 6446 __ bind(deferred->exit()); |
6447 __ bind(&done); | 6447 __ bind(&done); |
6448 } | 6448 } |
6449 | 6449 |
6450 | 6450 |
6451 #undef __ | 6451 #undef __ |
6452 | 6452 |
6453 } } // namespace v8::internal | 6453 } } // namespace v8::internal |
6454 | 6454 |
6455 #endif // V8_TARGET_ARCH_IA32 | 6455 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |