| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
| 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 4421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4432 __ Xor(src, src, Operand(0x80000000)); | 4432 __ Xor(src, src, Operand(0x80000000)); |
| 4433 } | 4433 } |
| 4434 __ mtc1(src, dbl_scratch); | 4434 __ mtc1(src, dbl_scratch); |
| 4435 __ cvt_d_w(dbl_scratch, dbl_scratch); | 4435 __ cvt_d_w(dbl_scratch, dbl_scratch); |
| 4436 } else { | 4436 } else { |
| 4437 __ Cvt_d_uw(dbl_scratch, src, f22); | 4437 __ Cvt_d_uw(dbl_scratch, src, f22); |
| 4438 } | 4438 } |
| 4439 | 4439 |
| 4440 if (FLAG_inline_new) { | 4440 if (FLAG_inline_new) { |
| 4441 __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); | 4441 __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); |
| 4442 __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT); | 4442 __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow); |
| 4443 __ Branch(&done); | 4443 __ Branch(&done); |
| 4444 } | 4444 } |
| 4445 | 4445 |
| 4446 // Slow case: Call the runtime system to do the number allocation. | 4446 // Slow case: Call the runtime system to do the number allocation. |
| 4447 __ bind(&slow); | 4447 __ bind(&slow); |
| 4448 { | 4448 { |
| 4449 // TODO(3095996): Put a valid pointer value in the stack slot where the | 4449 // TODO(3095996): Put a valid pointer value in the stack slot where the |
| 4450 // result register is stored, as this register is in the pointer map, but | 4450 // result register is stored, as this register is in the pointer map, but |
| 4451 // contains an integer value. | 4451 // contains an integer value. |
| 4452 __ mov(dst, zero_reg); | 4452 __ mov(dst, zero_reg); |
| 4453 | 4453 |
| 4454 // Preserve the value of all registers. | 4454 // Preserve the value of all registers. |
| 4455 PushSafepointRegistersScope scope(this); | 4455 PushSafepointRegistersScope scope(this); |
| 4456 | 4456 |
| 4457 // NumberTagI and NumberTagD use the context from the frame, rather than | 4457 // NumberTagI and NumberTagD use the context from the frame, rather than |
| 4458 // the environment's HContext or HInlinedContext value. | 4458 // the environment's HContext or HInlinedContext value. |
| 4459 // They only call Runtime::kAllocateHeapNumber. | 4459 // They only call Runtime::kAllocateHeapNumber. |
| 4460 // The corresponding HChange instructions are added in a phase that does | 4460 // The corresponding HChange instructions are added in a phase that does |
| 4461 // not have easy access to the local context. | 4461 // not have easy access to the local context. |
| 4462 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4462 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4463 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4463 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4464 RecordSafepointWithRegisters( | 4464 RecordSafepointWithRegisters( |
| 4465 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4465 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4466 __ Subu(v0, v0, kHeapObjectTag); | |
| 4467 __ StoreToSafepointRegisterSlot(v0, dst); | 4466 __ StoreToSafepointRegisterSlot(v0, dst); |
| 4468 } | 4467 } |
| 4469 | 4468 |
| 4470 | |
| 4471 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4469 // Done. Put the value in dbl_scratch into the value of the allocated heap |
| 4472 // number. | 4470 // number. |
| 4473 __ bind(&done); | 4471 __ bind(&done); |
| 4474 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); | 4472 __ sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset)); |
| 4475 __ Addu(dst, dst, kHeapObjectTag); | |
| 4476 } | 4473 } |
| 4477 | 4474 |
| 4478 | 4475 |
| 4479 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4476 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 4480 class DeferredNumberTagD final : public LDeferredCode { | 4477 class DeferredNumberTagD final : public LDeferredCode { |
| 4481 public: | 4478 public: |
| 4482 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4479 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
| 4483 : LDeferredCode(codegen), instr_(instr) { } | 4480 : LDeferredCode(codegen), instr_(instr) { } |
| 4484 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } | 4481 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } |
| 4485 LInstruction* instr() override { return instr_; } | 4482 LInstruction* instr() override { return instr_; } |
| 4486 | 4483 |
| 4487 private: | 4484 private: |
| 4488 LNumberTagD* instr_; | 4485 LNumberTagD* instr_; |
| 4489 }; | 4486 }; |
| 4490 | 4487 |
| 4491 DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 4488 DoubleRegister input_reg = ToDoubleRegister(instr->value()); |
| 4492 Register scratch = scratch0(); | 4489 Register scratch = scratch0(); |
| 4493 Register reg = ToRegister(instr->result()); | 4490 Register reg = ToRegister(instr->result()); |
| 4494 Register temp1 = ToRegister(instr->temp()); | 4491 Register temp1 = ToRegister(instr->temp()); |
| 4495 Register temp2 = ToRegister(instr->temp2()); | 4492 Register temp2 = ToRegister(instr->temp2()); |
| 4496 | 4493 |
| 4497 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 4494 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); |
| 4498 if (FLAG_inline_new) { | 4495 if (FLAG_inline_new) { |
| 4499 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4496 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
| 4500 // We want the untagged address first for performance | 4497 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); |
| 4501 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | |
| 4502 DONT_TAG_RESULT); | |
| 4503 } else { | 4498 } else { |
| 4504 __ Branch(deferred->entry()); | 4499 __ Branch(deferred->entry()); |
| 4505 } | 4500 } |
| 4506 __ bind(deferred->exit()); | 4501 __ bind(deferred->exit()); |
| 4507 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); | 4502 __ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
| 4508 // Now that we have finished with the object's real address tag it | 4503 // Now that we have finished with the object's real address tag it |
| 4509 __ Addu(reg, reg, kHeapObjectTag); | |
| 4510 } | 4504 } |
| 4511 | 4505 |
| 4512 | 4506 |
| 4513 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4507 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
| 4514 // TODO(3095996): Get rid of this. For now, we need to make the | 4508 // TODO(3095996): Get rid of this. For now, we need to make the |
| 4515 // result register contain a valid pointer because it is already | 4509 // result register contain a valid pointer because it is already |
| 4516 // contained in the register pointer map. | 4510 // contained in the register pointer map. |
| 4517 Register reg = ToRegister(instr->result()); | 4511 Register reg = ToRegister(instr->result()); |
| 4518 __ mov(reg, zero_reg); | 4512 __ mov(reg, zero_reg); |
| 4519 | 4513 |
| 4520 PushSafepointRegistersScope scope(this); | 4514 PushSafepointRegistersScope scope(this); |
| 4521 // NumberTagI and NumberTagD use the context from the frame, rather than | 4515 // NumberTagI and NumberTagD use the context from the frame, rather than |
| 4522 // the environment's HContext or HInlinedContext value. | 4516 // the environment's HContext or HInlinedContext value. |
| 4523 // They only call Runtime::kAllocateHeapNumber. | 4517 // They only call Runtime::kAllocateHeapNumber. |
| 4524 // The corresponding HChange instructions are added in a phase that does | 4518 // The corresponding HChange instructions are added in a phase that does |
| 4525 // not have easy access to the local context. | 4519 // not have easy access to the local context. |
| 4526 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4520 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4527 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4521 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4528 RecordSafepointWithRegisters( | 4522 RecordSafepointWithRegisters( |
| 4529 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4523 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4530 __ Subu(v0, v0, kHeapObjectTag); | |
| 4531 __ StoreToSafepointRegisterSlot(v0, reg); | 4524 __ StoreToSafepointRegisterSlot(v0, reg); |
| 4532 } | 4525 } |
| 4533 | 4526 |
| 4534 | 4527 |
| 4535 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 4528 void LCodeGen::DoSmiTag(LSmiTag* instr) { |
| 4536 HChange* hchange = instr->hydrogen(); | 4529 HChange* hchange = instr->hydrogen(); |
| 4537 Register input = ToRegister(instr->value()); | 4530 Register input = ToRegister(instr->value()); |
| 4538 Register output = ToRegister(instr->result()); | 4531 Register output = ToRegister(instr->result()); |
| 4539 if (hchange->CheckFlag(HValue::kCanOverflow) && | 4532 if (hchange->CheckFlag(HValue::kCanOverflow) && |
| 4540 hchange->value()->CheckFlag(HValue::kUint32)) { | 4533 hchange->value()->CheckFlag(HValue::kUint32)) { |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5068 }; | 5061 }; |
| 5069 | 5062 |
| 5070 DeferredAllocate* deferred = | 5063 DeferredAllocate* deferred = |
| 5071 new(zone()) DeferredAllocate(this, instr); | 5064 new(zone()) DeferredAllocate(this, instr); |
| 5072 | 5065 |
| 5073 Register result = ToRegister(instr->result()); | 5066 Register result = ToRegister(instr->result()); |
| 5074 Register scratch = ToRegister(instr->temp1()); | 5067 Register scratch = ToRegister(instr->temp1()); |
| 5075 Register scratch2 = ToRegister(instr->temp2()); | 5068 Register scratch2 = ToRegister(instr->temp2()); |
| 5076 | 5069 |
| 5077 // Allocate memory for the object. | 5070 // Allocate memory for the object. |
| 5078 AllocationFlags flags = TAG_OBJECT; | 5071 AllocationFlags flags = NO_ALLOCATION_FLAGS; |
| 5079 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 5072 if (instr->hydrogen()->MustAllocateDoubleAligned()) { |
| 5080 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 5073 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); |
| 5081 } | 5074 } |
| 5082 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 5075 if (instr->hydrogen()->IsOldSpaceAllocation()) { |
| 5083 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 5076 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5084 flags = static_cast<AllocationFlags>(flags | PRETENURE); | 5077 flags = static_cast<AllocationFlags>(flags | PRETENURE); |
| 5085 } | 5078 } |
| 5086 if (instr->size()->IsConstantOperand()) { | 5079 if (instr->size()->IsConstantOperand()) { |
| 5087 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5080 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 5088 CHECK(size <= Page::kMaxRegularHeapObjectSize); | 5081 CHECK(size <= Page::kMaxRegularHeapObjectSize); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5538 __ lw(result, FieldMemOperand(scratch, | 5531 __ lw(result, FieldMemOperand(scratch, |
| 5539 FixedArray::kHeaderSize - kPointerSize)); | 5532 FixedArray::kHeaderSize - kPointerSize)); |
| 5540 __ bind(deferred->exit()); | 5533 __ bind(deferred->exit()); |
| 5541 __ bind(&done); | 5534 __ bind(&done); |
| 5542 } | 5535 } |
| 5543 | 5536 |
| 5544 #undef __ | 5537 #undef __ |
| 5545 | 5538 |
| 5546 } // namespace internal | 5539 } // namespace internal |
| 5547 } // namespace v8 | 5540 } // namespace v8 |
| OLD | NEW |