| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 411 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
| 412 HConstant* constant = chunk_->LookupConstant(op); | 412 HConstant* constant = chunk_->LookupConstant(op); |
| 413 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 413 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
| 414 return constant->handle(isolate()); | 414 return constant->handle(isolate()); |
| 415 } | 415 } |
| 416 | 416 |
| 417 | 417 |
| 418 static int ArgumentsOffsetWithoutFrame(int index) { |
| 419 ASSERT(index < 0); |
| 420 return -(index + 1) * kPointerSize + kPCOnStackSize; |
| 421 } |
| 422 |
| 423 |
| 418 Operand LCodeGen::ToOperand(LOperand* op) const { | 424 Operand LCodeGen::ToOperand(LOperand* op) const { |
| 419 // Does not handle registers. In X64 assembler, plain registers are not | 425 // Does not handle registers. In X64 assembler, plain registers are not |
| 420 // representable as an Operand. | 426 // representable as an Operand. |
| 421 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); | 427 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 422 return Operand(rbp, StackSlotOffset(op->index())); | 428 if (NeedsEagerFrame()) { |
| 429 return Operand(rbp, StackSlotOffset(op->index())); |
| 430 } else { |
| 431 // Retrieve parameter without eager stack-frame relative to the |
| 432 // stack-pointer. |
| 433 return Operand(rsp, ArgumentsOffsetWithoutFrame(op->index())); |
| 434 } |
| 423 } | 435 } |
| 424 | 436 |
| 425 | 437 |
| 426 void LCodeGen::WriteTranslation(LEnvironment* environment, | 438 void LCodeGen::WriteTranslation(LEnvironment* environment, |
| 427 Translation* translation) { | 439 Translation* translation) { |
| 428 if (environment == NULL) return; | 440 if (environment == NULL) return; |
| 429 | 441 |
| 430 // The translation includes one command per value in the environment. | 442 // The translation includes one command per value in the environment. |
| 431 int translation_size = environment->translation_size(); | 443 int translation_size = environment->translation_size(); |
| 432 // The output frame height does not include the parameters. | 444 // The output frame height does not include the parameters. |
| (...skipping 1806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 __ subq(rsp, Immediate(kDoubleSize)); | 2251 __ subq(rsp, Immediate(kDoubleSize)); |
| 2240 __ movsd(MemOperand(rsp, 0), input_reg); | 2252 __ movsd(MemOperand(rsp, 0), input_reg); |
| 2241 __ addq(rsp, Immediate(kDoubleSize)); | 2253 __ addq(rsp, Immediate(kDoubleSize)); |
| 2242 | 2254 |
| 2243 int offset = sizeof(kHoleNanUpper32); | 2255 int offset = sizeof(kHoleNanUpper32); |
| 2244 __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32)); | 2256 __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32)); |
| 2245 EmitBranch(instr, equal); | 2257 EmitBranch(instr, equal); |
| 2246 } | 2258 } |
| 2247 | 2259 |
| 2248 | 2260 |
| 2261 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { |
| 2262 Representation rep = instr->hydrogen()->value()->representation(); |
| 2263 ASSERT(!rep.IsInteger32()); |
| 2264 |
| 2265 if (rep.IsDouble()) { |
| 2266 XMMRegister value = ToDoubleRegister(instr->value()); |
| 2267 XMMRegister xmm_scratch = double_scratch0(); |
| 2268 __ xorps(xmm_scratch, xmm_scratch); |
| 2269 __ ucomisd(xmm_scratch, value); |
| 2270 EmitFalseBranch(instr, not_equal); |
| 2271 __ movmskpd(kScratchRegister, value); |
| 2272 __ testl(kScratchRegister, Immediate(1)); |
| 2273 EmitBranch(instr, not_zero); |
| 2274 } else { |
| 2275 Register value = ToRegister(instr->value()); |
| 2276 Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); |
| 2277 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK); |
| 2278 __ cmpl(FieldOperand(value, HeapNumber::kExponentOffset), |
| 2279 Immediate(0x80000000)); |
| 2280 EmitFalseBranch(instr, not_equal); |
| 2281 __ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset), |
| 2282 Immediate(0x00000000)); |
| 2283 EmitBranch(instr, equal); |
| 2284 } |
| 2285 } |
| 2286 |
| 2287 |
| 2249 Condition LCodeGen::EmitIsObject(Register input, | 2288 Condition LCodeGen::EmitIsObject(Register input, |
| 2250 Label* is_not_object, | 2289 Label* is_not_object, |
| 2251 Label* is_object) { | 2290 Label* is_object) { |
| 2252 ASSERT(!input.is(kScratchRegister)); | 2291 ASSERT(!input.is(kScratchRegister)); |
| 2253 | 2292 |
| 2254 __ JumpIfSmi(input, is_not_object); | 2293 __ JumpIfSmi(input, is_not_object); |
| 2255 | 2294 |
| 2256 __ CompareRoot(input, Heap::kNullValueRootIndex); | 2295 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 2257 __ j(equal, is_object); | 2296 __ j(equal, is_object); |
| 2258 | 2297 |
| (...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3876 } | 3915 } |
| 3877 | 3916 |
| 3878 | 3917 |
| 3879 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3918 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
| 3880 ASSERT(ToRegister(instr->context()).is(rsi)); | 3919 ASSERT(ToRegister(instr->context()).is(rsi)); |
| 3881 ASSERT(ToRegister(instr->function()).is(rdi)); | 3920 ASSERT(ToRegister(instr->function()).is(rdi)); |
| 3882 ASSERT(ToRegister(instr->result()).is(rax)); | 3921 ASSERT(ToRegister(instr->result()).is(rax)); |
| 3883 | 3922 |
| 3884 int arity = instr->arity(); | 3923 int arity = instr->arity(); |
| 3885 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); | 3924 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); |
| 3886 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3925 if (instr->hydrogen()->IsTailCall()) { |
| 3926 if (NeedsEagerFrame()) __ leave(); |
| 3927 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
| 3928 } else { |
| 3929 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3930 } |
| 3887 } | 3931 } |
| 3888 | 3932 |
| 3889 | 3933 |
| 3890 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 3934 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
| 3891 ASSERT(ToRegister(instr->context()).is(rsi)); | 3935 ASSERT(ToRegister(instr->context()).is(rsi)); |
| 3892 ASSERT(ToRegister(instr->result()).is(rax)); | 3936 ASSERT(ToRegister(instr->result()).is(rax)); |
| 3893 int arity = instr->arity(); | 3937 int arity = instr->arity(); |
| 3894 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; | 3938 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
| 3895 Handle<Code> ic = | 3939 Handle<Code> ic = |
| 3896 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3940 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5197 if (instr->size()->IsRegister()) { | 5241 if (instr->size()->IsRegister()) { |
| 5198 Register size = ToRegister(instr->size()); | 5242 Register size = ToRegister(instr->size()); |
| 5199 ASSERT(!size.is(result)); | 5243 ASSERT(!size.is(result)); |
| 5200 __ Integer32ToSmi(size, size); | 5244 __ Integer32ToSmi(size, size); |
| 5201 __ push(size); | 5245 __ push(size); |
| 5202 } else { | 5246 } else { |
| 5203 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5247 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 5204 __ Push(Smi::FromInt(size)); | 5248 __ Push(Smi::FromInt(size)); |
| 5205 } | 5249 } |
| 5206 | 5250 |
| 5251 int flags = 0; |
| 5207 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { | 5252 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { |
| 5208 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); | 5253 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); |
| 5209 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); | 5254 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5210 CallRuntimeFromDeferred( | 5255 flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE); |
| 5211 Runtime::kAllocateInOldPointerSpace, 1, instr, instr->context()); | |
| 5212 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { | 5256 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { |
| 5213 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); | 5257 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5214 CallRuntimeFromDeferred( | 5258 flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); |
| 5215 Runtime::kAllocateInOldDataSpace, 1, instr, instr->context()); | |
| 5216 } else { | 5259 } else { |
| 5217 CallRuntimeFromDeferred( | 5260 flags = AllocateTargetSpace::update(flags, NEW_SPACE); |
| 5218 Runtime::kAllocateInNewSpace, 1, instr, instr->context()); | |
| 5219 } | 5261 } |
| 5262 __ Push(Smi::FromInt(flags)); |
| 5263 |
| 5264 CallRuntimeFromDeferred( |
| 5265 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); |
| 5220 __ StoreToSafepointRegisterSlot(result, rax); | 5266 __ StoreToSafepointRegisterSlot(result, rax); |
| 5221 } | 5267 } |
| 5222 | 5268 |
| 5223 | 5269 |
| 5224 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 5270 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { |
| 5225 ASSERT(ToRegister(instr->value()).is(rax)); | 5271 ASSERT(ToRegister(instr->value()).is(rax)); |
| 5226 __ push(rax); | 5272 __ push(rax); |
| 5227 CallRuntime(Runtime::kToFastProperties, 1, instr); | 5273 CallRuntime(Runtime::kToFastProperties, 1, instr); |
| 5228 } | 5274 } |
| 5229 | 5275 |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5646 FixedArray::kHeaderSize - kPointerSize)); | 5692 FixedArray::kHeaderSize - kPointerSize)); |
| 5647 __ bind(&done); | 5693 __ bind(&done); |
| 5648 } | 5694 } |
| 5649 | 5695 |
| 5650 | 5696 |
| 5651 #undef __ | 5697 #undef __ |
| 5652 | 5698 |
| 5653 } } // namespace v8::internal | 5699 } } // namespace v8::internal |
| 5654 | 5700 |
| 5655 #endif // V8_TARGET_ARCH_X64 | 5701 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |