 Chromium Code Reviews
 Chromium Code Reviews Issue 1899813003:
  [crankshaft] Fragmentation-free allocation folding.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1899813003:
  [crankshaft] Fragmentation-free allocation folding.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 | 
| 6 | 6 | 
| 7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" | 7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" | 
| 8 | 8 | 
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" | 
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" | 
| (...skipping 4852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4863 // Allocate memory for the object. | 4863 // Allocate memory for the object. | 
| 4864 AllocationFlags flags = NO_ALLOCATION_FLAGS; | 4864 AllocationFlags flags = NO_ALLOCATION_FLAGS; | 
| 4865 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 4865 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 
| 4866 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 4866 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 
| 4867 } | 4867 } | 
| 4868 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 4868 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 
| 4869 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 4869 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 
| 4870 flags = static_cast<AllocationFlags>(flags | PRETENURE); | 4870 flags = static_cast<AllocationFlags>(flags | PRETENURE); | 
| 4871 } | 4871 } | 
| 4872 | 4872 | 
| 4873 if (instr->hydrogen()->IsAllocationFoldingDominator()) { | |
| 4874 flags = static_cast<AllocationFlags>(flags | ALLOCATION_FOLDING_DOMINATOR); | |
| 4875 } | |
| 4876 | |
| 4877 if (instr->hydrogen()->IsAllocationFolded()) { | |
| 4878 flags = static_cast<AllocationFlags>(flags | ALLOCATION_FOLDED); | |
| 4879 } | |
| 4880 | |
| 4873 if (instr->size()->IsConstantOperand()) { | 4881 if (instr->size()->IsConstantOperand()) { | 
| 4874 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 4882 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 
| 4875 CHECK(size <= Page::kMaxRegularHeapObjectSize); | 4883 CHECK(size <= Page::kMaxRegularHeapObjectSize); | 
| 4876 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 4884 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 
| 4877 } else { | 4885 } else { | 
| 4878 Register size = ToRegister(instr->size()); | 4886 Register size = ToRegister(instr->size()); | 
| 4879 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 4887 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); | 
| 4880 } | 4888 } | 
| 4881 | 4889 | 
| 4882 __ bind(deferred->exit()); | 4890 __ bind(deferred->exit()); | 
| 4883 | 4891 | 
| 4884 if (instr->hydrogen()->MustPrefillWithFiller()) { | 4892 if (instr->hydrogen()->MustPrefillWithFiller()) { | 
| 4885 if (instr->size()->IsConstantOperand()) { | 4893 if (instr->size()->IsConstantOperand()) { | 
| 4886 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 4894 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 
| 4887 __ mov(temp, (size / kPointerSize) - 1); | 4895 __ mov(temp, (size / kPointerSize) - 1); | 
| 4888 } else { | 4896 } else { | 
| 4889 temp = ToRegister(instr->size()); | 4897 temp = ToRegister(instr->size()); | 
| 4890 __ shr(temp, kPointerSizeLog2); | 4898 __ shr(temp, kPointerSizeLog2); | 
| 4891 __ dec(temp); | 4899 __ dec(temp); | 
| 4892 } | 4900 } | 
| 4893 Label loop; | 4901 Label loop; | 
| 4894 __ bind(&loop); | 4902 __ bind(&loop); | 
| 4895 __ mov(FieldOperand(result, temp, times_pointer_size, 0), | 4903 __ mov(FieldOperand(result, temp, times_pointer_size, 0), | 
| 4896 isolate()->factory()->one_pointer_filler_map()); | 4904 isolate()->factory()->one_pointer_filler_map()); | 
| 4897 __ dec(temp); | 4905 __ dec(temp); | 
| 4898 __ j(not_zero, &loop); | 4906 __ j(not_zero, &loop); | 
| 4899 } | 4907 } | 
| 4900 } | 4908 } | 
| 4901 | 4909 | 
| 4910 void LCodeGen::DoFastAllocate(LFastAllocate* instr) { | |
| 4911 DCHECK(instr->hydrogen()->IsAllocationFolded()); | |
| 4912 Register result = ToRegister(instr->result()); | |
| 4913 Register temp = ToRegister(instr->temp()); | |
| 4914 | |
| 4915 AllocationFlags flags = NO_ALLOCATION_FLAGS; | |
| 4916 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | |
| 4917 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | |
| 4918 } | |
| 4919 if (instr->hydrogen()->IsOldSpaceAllocation()) { | |
| 4920 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | |
| 4921 flags = static_cast<AllocationFlags>(flags | PRETENURE); | |
| 4922 } | |
| 4923 if (!instr->hydrogen()->IsAllocationFoldingDominator()) { | |
| 4924 if (instr->size()->IsConstantOperand()) { | |
| 4925 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | |
| 4926 CHECK(size <= Page::kMaxRegularHeapObjectSize); | |
| 4927 __ FastAllocate(size, result, temp, flags); | |
| 4928 } else { | |
| 4929 Register size = ToRegister(instr->size()); | |
| 4930 __ FastAllocate(size, result, temp, flags); | |
| 4931 } | |
| 4932 } | |
| 4933 } | |
| 4902 | 4934 | 
| 4903 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 4935 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 
| 4904 Register result = ToRegister(instr->result()); | 4936 Register result = ToRegister(instr->result()); | 
| 4905 | 4937 | 
| 4906 // TODO(3095996): Get rid of this. For now, we need to make the | 4938 // TODO(3095996): Get rid of this. For now, we need to make the | 
| 4907 // result register contain a valid pointer because it is already | 4939 // result register contain a valid pointer because it is already | 
| 4908 // contained in the register pointer map. | 4940 // contained in the register pointer map. | 
| 4909 __ Move(result, Immediate(Smi::FromInt(0))); | 4941 __ Move(result, Immediate(Smi::FromInt(0))); | 
| 4910 | 4942 | 
| 4911 PushSafepointRegistersScope scope(this); | 4943 PushSafepointRegistersScope scope(this); | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 4931 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 4963 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 
| 4932 flags = AllocateTargetSpace::update(flags, OLD_SPACE); | 4964 flags = AllocateTargetSpace::update(flags, OLD_SPACE); | 
| 4933 } else { | 4965 } else { | 
| 4934 flags = AllocateTargetSpace::update(flags, NEW_SPACE); | 4966 flags = AllocateTargetSpace::update(flags, NEW_SPACE); | 
| 4935 } | 4967 } | 
| 4936 __ push(Immediate(Smi::FromInt(flags))); | 4968 __ push(Immediate(Smi::FromInt(flags))); | 
| 4937 | 4969 | 
| 4938 CallRuntimeFromDeferred( | 4970 CallRuntimeFromDeferred( | 
| 4939 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); | 4971 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); | 
| 4940 __ StoreToSafepointRegisterSlot(result, eax); | 4972 __ StoreToSafepointRegisterSlot(result, eax); | 
| 4973 | |
| 4974 if (instr->hydrogen()->IsAllocationFoldingDominator()) { | |
| 4975 AllocationFlags allocation_flags = NO_ALLOCATION_FLAGS; | |
| 4976 if (instr->hydrogen()->IsOldSpaceAllocation()) { | |
| 4977 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | |
| 4978 allocation_flags = static_cast<AllocationFlags>(flags | PRETENURE); | |
| 4979 } | |
| 4980 // If the allocation folding dominator allocate triggered a GC, allocation | |
| 4981 // happend in the runtime. We have to reset the top pointer to virtually | |
| 4982 // undo the allocation. | |
| 4983 ExternalReference allocation_top = | |
| 4984 AllocationUtils::GetAllocationTopReference(isolate(), allocation_flags); | |
| 4985 __ sub(eax, Immediate(kHeapObjectTag)); | |
| 4986 __ mov(Operand::StaticVariable(allocation_top), eax); | |
| 
Michael Lippautz
2016/05/10 08:32:58
***~~~ landmine detected ~~~***
 | |
| 4987 __ add(eax, Immediate(kHeapObjectTag)); | |
| 4988 } | |
| 4941 } | 4989 } | 
| 4942 | 4990 | 
| 4943 | 4991 | 
| 4944 void LCodeGen::DoTypeof(LTypeof* instr) { | 4992 void LCodeGen::DoTypeof(LTypeof* instr) { | 
| 4945 DCHECK(ToRegister(instr->context()).is(esi)); | 4993 DCHECK(ToRegister(instr->context()).is(esi)); | 
| 4946 DCHECK(ToRegister(instr->value()).is(ebx)); | 4994 DCHECK(ToRegister(instr->value()).is(ebx)); | 
| 4947 Label end, do_call; | 4995 Label end, do_call; | 
| 4948 Register value_register = ToRegister(instr->value()); | 4996 Register value_register = ToRegister(instr->value()); | 
| 4949 __ JumpIfNotSmi(value_register, &do_call); | 4997 __ JumpIfNotSmi(value_register, &do_call); | 
| 4950 __ mov(eax, Immediate(isolate()->factory()->number_string())); | 4998 __ mov(eax, Immediate(isolate()->factory()->number_string())); | 
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5288 __ bind(deferred->exit()); | 5336 __ bind(deferred->exit()); | 
| 5289 __ bind(&done); | 5337 __ bind(&done); | 
| 5290 } | 5338 } | 
| 5291 | 5339 | 
| 5292 #undef __ | 5340 #undef __ | 
| 5293 | 5341 | 
| 5294 } // namespace internal | 5342 } // namespace internal | 
| 5295 } // namespace v8 | 5343 } // namespace v8 | 
| 5296 | 5344 | 
| 5297 #endif // V8_TARGET_ARCH_IA32 | 5345 #endif // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |