| 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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 SaveCallerDoubles(); | 286 SaveCallerDoubles(); |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 | 289 |
| 290 // Possibly allocate a local context. | 290 // Possibly allocate a local context. |
| 291 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 291 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 292 if (heap_slots > 0) { | 292 if (heap_slots > 0) { |
| 293 Comment(";;; Allocate local context"); | 293 Comment(";;; Allocate local context"); |
| 294 // Argument to NewContext is the function, which is still in edi. | 294 // Argument to NewContext is the function, which is still in edi. |
| 295 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 295 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 296 FastNewContextStub stub(heap_slots); | 296 FastNewContextStub stub(isolate(), heap_slots); |
| 297 __ CallStub(&stub); | 297 __ CallStub(&stub); |
| 298 } else { | 298 } else { |
| 299 __ push(edi); | 299 __ push(edi); |
| 300 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 300 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
| 301 } | 301 } |
| 302 RecordSafepoint(Safepoint::kNoLazyDeopt); | 302 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 303 // Context is returned in eax. It replaces the context passed to us. | 303 // Context is returned in eax. It replaces the context passed to us. |
| 304 // It's saved in the stack and kept live in esi. | 304 // It's saved in the stack and kept live in esi. |
| 305 __ mov(esi, eax); | 305 __ mov(esi, eax); |
| 306 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); | 306 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); |
| (...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 void LCodeGen::DoParameter(LParameter* instr) { | 1343 void LCodeGen::DoParameter(LParameter* instr) { |
| 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; | 1353 RegExpExecStub stub(isolate()); |
| 1354 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1354 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1355 break; | 1355 break; |
| 1356 } | 1356 } |
| 1357 case CodeStub::SubString: { | 1357 case CodeStub::SubString: { |
| 1358 SubStringStub stub; | 1358 SubStringStub stub(isolate()); |
| 1359 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1359 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1360 break; | 1360 break; |
| 1361 } | 1361 } |
| 1362 case CodeStub::StringCompare: { | 1362 case CodeStub::StringCompare: { |
| 1363 StringCompareStub stub; | 1363 StringCompareStub stub(isolate()); |
| 1364 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1364 CallCode(stub.GetCode(isolate()), 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) { |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2350 } | 2350 } |
| 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(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(isolate()), 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(); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2968 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { | 2968 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { |
| 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(InstanceofStub::kArgsInRegisters); | 2978 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); |
| 2979 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2979 CallCode(stub.GetCode(isolate()), 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); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3057 Label* map_check) { | 3057 Label* map_check) { |
| 3058 PushSafepointRegistersScope scope(this); | 3058 PushSafepointRegistersScope scope(this); |
| 3059 | 3059 |
| 3060 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; | 3060 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; |
| 3061 flags = static_cast<InstanceofStub::Flags>( | 3061 flags = static_cast<InstanceofStub::Flags>( |
| 3062 flags | InstanceofStub::kArgsInRegisters); | 3062 flags | InstanceofStub::kArgsInRegisters); |
| 3063 flags = static_cast<InstanceofStub::Flags>( | 3063 flags = static_cast<InstanceofStub::Flags>( |
| 3064 flags | InstanceofStub::kCallSiteInlineCheck); | 3064 flags | InstanceofStub::kCallSiteInlineCheck); |
| 3065 flags = static_cast<InstanceofStub::Flags>( | 3065 flags = static_cast<InstanceofStub::Flags>( |
| 3066 flags | InstanceofStub::kReturnTrueFalseObject); | 3066 flags | InstanceofStub::kReturnTrueFalseObject); |
| 3067 InstanceofStub stub(flags); | 3067 InstanceofStub stub(isolate(), flags); |
| 3068 | 3068 |
| 3069 // Get the temp register reserved by the instruction. This needs to be a | 3069 // Get the temp register reserved by the instruction. This needs to be a |
| 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; |
| (...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4160 // Having marked this as a call, we can use any registers. | 4160 // Having marked this as a call, we can use any registers. |
| 4161 // Just make sure that the input/output registers are the expected ones. | 4161 // Just make sure that the input/output registers are the expected ones. |
| 4162 ASSERT(!instr->right()->IsDoubleRegister() || | 4162 ASSERT(!instr->right()->IsDoubleRegister() || |
| 4163 ToDoubleRegister(instr->right()).is(xmm1)); | 4163 ToDoubleRegister(instr->right()).is(xmm1)); |
| 4164 ASSERT(!instr->right()->IsRegister() || | 4164 ASSERT(!instr->right()->IsRegister() || |
| 4165 ToRegister(instr->right()).is(eax)); | 4165 ToRegister(instr->right()).is(eax)); |
| 4166 ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); | 4166 ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); |
| 4167 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); | 4167 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); |
| 4168 | 4168 |
| 4169 if (exponent_type.IsSmi()) { | 4169 if (exponent_type.IsSmi()) { |
| 4170 MathPowStub stub(MathPowStub::TAGGED); | 4170 MathPowStub stub(isolate(), MathPowStub::TAGGED); |
| 4171 __ CallStub(&stub); | 4171 __ CallStub(&stub); |
| 4172 } else if (exponent_type.IsTagged()) { | 4172 } else if (exponent_type.IsTagged()) { |
| 4173 Label no_deopt; | 4173 Label no_deopt; |
| 4174 __ JumpIfSmi(eax, &no_deopt); | 4174 __ JumpIfSmi(eax, &no_deopt); |
| 4175 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); | 4175 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); |
| 4176 DeoptimizeIf(not_equal, instr->environment()); | 4176 DeoptimizeIf(not_equal, instr->environment()); |
| 4177 __ bind(&no_deopt); | 4177 __ bind(&no_deopt); |
| 4178 MathPowStub stub(MathPowStub::TAGGED); | 4178 MathPowStub stub(isolate(), MathPowStub::TAGGED); |
| 4179 __ CallStub(&stub); | 4179 __ CallStub(&stub); |
| 4180 } else if (exponent_type.IsInteger32()) { | 4180 } else if (exponent_type.IsInteger32()) { |
| 4181 MathPowStub stub(MathPowStub::INTEGER); | 4181 MathPowStub stub(isolate(), MathPowStub::INTEGER); |
| 4182 __ CallStub(&stub); | 4182 __ CallStub(&stub); |
| 4183 } else { | 4183 } else { |
| 4184 ASSERT(exponent_type.IsDouble()); | 4184 ASSERT(exponent_type.IsDouble()); |
| 4185 MathPowStub stub(MathPowStub::DOUBLE); | 4185 MathPowStub stub(isolate(), MathPowStub::DOUBLE); |
| 4186 __ CallStub(&stub); | 4186 __ CallStub(&stub); |
| 4187 } | 4187 } |
| 4188 } | 4188 } |
| 4189 | 4189 |
| 4190 | 4190 |
| 4191 void LCodeGen::DoMathLog(LMathLog* instr) { | 4191 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 4192 CpuFeatureScope scope(masm(), SSE2); | 4192 CpuFeatureScope scope(masm(), SSE2); |
| 4193 ASSERT(instr->value()->Equals(instr->result())); | 4193 ASSERT(instr->value()->Equals(instr->result())); |
| 4194 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4194 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4195 XMMRegister xmm_scratch = double_scratch0(); | 4195 XMMRegister xmm_scratch = double_scratch0(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4268 } | 4268 } |
| 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(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(isolate()), 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(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(isolate()), 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(kind, override_mode); | 4310 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); |
| 4311 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4311 CallCode(stub.GetCode(isolate()), 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(holey_kind, override_mode); | 4323 ArraySingleArgumentConstructorStub stub(isolate(), |
| 4324 holey_kind, |
| 4325 override_mode); |
| 4324 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4326 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4325 __ jmp(&done, Label::kNear); | 4327 __ jmp(&done, Label::kNear); |
| 4326 __ bind(&packed_case); | 4328 __ bind(&packed_case); |
| 4327 } | 4329 } |
| 4328 | 4330 |
| 4329 ArraySingleArgumentConstructorStub stub(kind, override_mode); | 4331 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); |
| 4330 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4332 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4331 __ bind(&done); | 4333 __ bind(&done); |
| 4332 } else { | 4334 } else { |
| 4333 ArrayNArgumentsConstructorStub stub(kind, override_mode); | 4335 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); |
| 4334 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4336 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4335 } | 4337 } |
| 4336 } | 4338 } |
| 4337 | 4339 |
| 4338 | 4340 |
| 4339 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4341 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
| 4340 ASSERT(ToRegister(instr->context()).is(esi)); | 4342 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4341 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); | 4343 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); |
| 4342 } | 4344 } |
| 4343 | 4345 |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4776 ASSERT_NE(instr->temp(), NULL); | 4778 ASSERT_NE(instr->temp(), NULL); |
| 4777 __ RecordWriteForMap(object_reg, to_map, new_map_reg, | 4779 __ RecordWriteForMap(object_reg, to_map, new_map_reg, |
| 4778 ToRegister(instr->temp()), | 4780 ToRegister(instr->temp()), |
| 4779 kDontSaveFPRegs); | 4781 kDontSaveFPRegs); |
| 4780 } else { | 4782 } else { |
| 4781 ASSERT(ToRegister(instr->context()).is(esi)); | 4783 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4782 ASSERT(object_reg.is(eax)); | 4784 ASSERT(object_reg.is(eax)); |
| 4783 PushSafepointRegistersScope scope(this); | 4785 PushSafepointRegistersScope scope(this); |
| 4784 __ mov(ebx, to_map); | 4786 __ mov(ebx, to_map); |
| 4785 bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; | 4787 bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; |
| 4786 TransitionElementsKindStub stub(from_kind, to_kind, is_js_array); | 4788 TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); |
| 4787 __ CallStub(&stub); | 4789 __ CallStub(&stub); |
| 4788 RecordSafepointWithLazyDeopt(instr, | 4790 RecordSafepointWithLazyDeopt(instr, |
| 4789 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 4791 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
| 4790 } | 4792 } |
| 4791 __ bind(¬_applicable); | 4793 __ bind(¬_applicable); |
| 4792 } | 4794 } |
| 4793 | 4795 |
| 4794 | 4796 |
| 4795 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4797 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 4796 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4798 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4900 __ push(char_code); | 4902 __ push(char_code); |
| 4901 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); | 4903 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); |
| 4902 __ StoreToSafepointRegisterSlot(result, eax); | 4904 __ StoreToSafepointRegisterSlot(result, eax); |
| 4903 } | 4905 } |
| 4904 | 4906 |
| 4905 | 4907 |
| 4906 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4908 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4907 ASSERT(ToRegister(instr->context()).is(esi)); | 4909 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4908 ASSERT(ToRegister(instr->left()).is(edx)); | 4910 ASSERT(ToRegister(instr->left()).is(edx)); |
| 4909 ASSERT(ToRegister(instr->right()).is(eax)); | 4911 ASSERT(ToRegister(instr->right()).is(eax)); |
| 4910 StringAddStub stub(instr->hydrogen()->flags(), | 4912 StringAddStub stub(isolate(), |
| 4913 instr->hydrogen()->flags(), |
| 4911 instr->hydrogen()->pretenure_flag()); | 4914 instr->hydrogen()->pretenure_flag()); |
| 4912 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4915 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4913 } | 4916 } |
| 4914 | 4917 |
| 4915 | 4918 |
| 4916 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4919 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 4917 LOperand* input = instr->value(); | 4920 LOperand* input = instr->value(); |
| 4918 LOperand* output = instr->result(); | 4921 LOperand* output = instr->result(); |
| 4919 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4922 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4920 ASSERT(output->IsDoubleRegister()); | 4923 ASSERT(output->IsDoubleRegister()); |
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6036 } | 6039 } |
| 6037 } | 6040 } |
| 6038 | 6041 |
| 6039 | 6042 |
| 6040 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 6043 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
| 6041 ASSERT(ToRegister(instr->context()).is(esi)); | 6044 ASSERT(ToRegister(instr->context()).is(esi)); |
| 6042 // Use the fast case closure allocation code that allocates in new | 6045 // Use the fast case closure allocation code that allocates in new |
| 6043 // space for nested functions that don't need literals cloning. | 6046 // space for nested functions that don't need literals cloning. |
| 6044 bool pretenure = instr->hydrogen()->pretenure(); | 6047 bool pretenure = instr->hydrogen()->pretenure(); |
| 6045 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 6048 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
| 6046 FastNewClosureStub stub(instr->hydrogen()->strict_mode(), | 6049 FastNewClosureStub stub(isolate(), |
| 6050 instr->hydrogen()->strict_mode(), |
| 6047 instr->hydrogen()->is_generator()); | 6051 instr->hydrogen()->is_generator()); |
| 6048 __ mov(ebx, Immediate(instr->hydrogen()->shared_info())); | 6052 __ mov(ebx, Immediate(instr->hydrogen()->shared_info())); |
| 6049 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 6053 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 6050 } else { | 6054 } else { |
| 6051 __ push(esi); | 6055 __ push(esi); |
| 6052 __ push(Immediate(instr->hydrogen()->shared_info())); | 6056 __ push(Immediate(instr->hydrogen()->shared_info())); |
| 6053 __ push(Immediate(pretenure ? factory()->true_value() | 6057 __ push(Immediate(pretenure ? factory()->true_value() |
| 6054 : factory()->false_value())); | 6058 : factory()->false_value())); |
| 6055 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); | 6059 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
| 6056 } | 6060 } |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6442 __ bind(deferred->exit()); | 6446 __ bind(deferred->exit()); |
| 6443 __ bind(&done); | 6447 __ bind(&done); |
| 6444 } | 6448 } |
| 6445 | 6449 |
| 6446 | 6450 |
| 6447 #undef __ | 6451 #undef __ |
| 6448 | 6452 |
| 6449 } } // namespace v8::internal | 6453 } } // namespace v8::internal |
| 6450 | 6454 |
| 6451 #endif // V8_TARGET_ARCH_IA32 | 6455 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |