void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
- stream->Add(" + %d", offset());
+ stream->Add(" + ");
+ offset()->PrintTo(stream);
}
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
- HInnerAllocatedObject* inner_object) {
- LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
- LInnerAllocatedObject* result =
- new(zone()) LInnerAllocatedObject(base_object);
- return DefineAsRegister(result);
+ HInnerAllocatedObject* instr) {
+ LOperand* base_object = UseRegisterAtStart(instr->base_object());
+ LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
+ return DefineAsRegister(
+ new(zone()) LInnerAllocatedObject(base_object, offset));
}
};
-class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 2, 0> {
public:
- explicit LInnerAllocatedObject(LOperand* base_object) {
+ LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
inputs_[0] = base_object;
+ inputs_[1] = offset;
}
- LOperand* base_object() { return inputs_[0]; }
- int offset() { return hydrogen()->offset(); }
+ LOperand* base_object() const { return inputs_[0]; }
+ LOperand* offset() const { return inputs_[1]; }
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
- DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+ DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
};
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
- __ add(result, base, Operand(instr->offset()));
+ if (instr->offset()->IsConstantOperand()) {
+ LConstantOperand* offset = LConstantOperand::cast(instr->offset());
+ __ add(result, base, Operand(ToInteger32(offset)));
+ } else {
+ Register offset = ToRegister(instr->offset());
+ __ add(result, base, offset);
+ }
}
ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
if (FLAG_allocation_site_pretenuring) {
- BuildCreateAllocationMemento(object, object_size, allocation_site);
+ BuildCreateAllocationMemento(
+ object, Add<HConstant>(object_size), allocation_site);
}
environment()->Push(object);
HInnerAllocatedObject::New(zone,
context(),
dominator_allocate,
- dominator_size_constant,
+ dominator_size,
type());
dominated_allocate_instr->InsertBefore(this);
DeleteAndReplaceWith(dominated_allocate_instr);
void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
ASSERT(filler_free_space_size_ == NULL);
Zone* zone = block()->zone();
- int32_t dominator_size =
- HConstant::cast(dominating_allocate_->size())->GetInteger32Constant();
HInstruction* free_space_instr =
HInnerAllocatedObject::New(zone, context(), dominating_allocate_,
- dominator_size, type());
+ dominating_allocate_->size(), type());
free_space_instr->InsertBefore(this);
HConstant* filler_map = HConstant::New(
zone,
};
-class HInnerAllocatedObject V8_FINAL: public HTemplateInstruction<1> {
+class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> {
public:
static HInnerAllocatedObject* New(Zone* zone,
HValue* context,
HValue* value,
- int offset,
+ HValue* offset,
HType type = HType::Tagged()) {
return new(zone) HInnerAllocatedObject(value, offset, type);
}
HValue* base_object() { return OperandAt(0); }
- int offset() { return offset_; }
+ HValue* offset() { return OperandAt(1); }
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
- return Representation::Tagged();
+ return index == 0 ? Representation::Tagged() : Representation::Integer32();
}
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
private:
- HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged())
- : HTemplateInstruction<1>(type), offset_(offset) {
+ HInnerAllocatedObject(HValue* value,
+ HValue* offset,
+ HType type = HType::Tagged())
+ : HTemplateInstruction<2>(type) {
ASSERT(value->IsAllocate());
SetOperandAt(0, value);
+ SetOperandAt(1, offset);
set_type(type);
set_representation(Representation::Tagged());
}
-
- int offset_;
};
length_field);
if (mode == TRACK_ALLOCATION_SITE) {
- BuildCreateAllocationMemento(array,
- JSArray::kSize,
- allocation_site_payload);
- if (FLAG_allocation_site_pretenuring) {
- // TODO(mvstanton): move this code into BuildCreateAllocationMemento when
- // constructed arrays also pay attention to pretenuring.
- HObjectAccess access =
- HObjectAccess::ForAllocationSiteOffset(
- AllocationSite::kMementoCreateCountOffset);
- HValue* create_info = Add<HLoadNamedField>(allocation_site_payload,
- access);
- HInstruction* new_create_info =
- AddUncasted<HAdd>(create_info, graph()->GetConstant1());
- new_create_info->ClearFlag(HValue::kCanOverflow);
- HStoreNamedField* store = Add<HStoreNamedField>(allocation_site_payload,
- access, new_create_info);
- // No write barrier needed to store a smi.
- store->SkipWriteBarrier();
- }
+ BuildCreateAllocationMemento(
+ array, Add<HConstant>(JSArray::kSize), allocation_site_payload);
}
int elements_location = JSArray::kSize;
elements_location += AllocationMemento::kSize;
}
- HValue* elements = Add<HInnerAllocatedObject>(array, elements_location);
+ HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>(
+ array, Add<HConstant>(elements_location));
Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
- return static_cast<HInnerAllocatedObject*>(elements);
+ return elements;
}
// Create an allocation site info if requested.
if (mode == TRACK_ALLOCATION_SITE) {
- BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site);
+ BuildCreateAllocationMemento(
+ object, Add<HConstant>(JSArray::kSize), allocation_site);
}
if (length > 0) {
}
-HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
- int previous_object_size,
- HValue* alloc_site) {
- ASSERT(alloc_site != NULL);
- HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
+void HGraphBuilder::BuildCreateAllocationMemento(
+ HValue* previous_object,
+ HValue* previous_object_size,
+ HValue* allocation_site) {
+ ASSERT(allocation_site != NULL);
+ HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>(
previous_object, previous_object_size);
- Handle<Map> alloc_memento_map =
- isolate()->factory()->allocation_memento_map();
- AddStoreMapConstant(alloc_memento, alloc_memento_map);
- HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
- Add<HStoreNamedField>(alloc_memento, access, alloc_site);
- return alloc_memento;
+ AddStoreMapConstant(
+ allocation_memento, isolate()->factory()->allocation_memento_map());
+ Add<HStoreNamedField>(
+ allocation_memento,
+ HObjectAccess::ForAllocationMementoSite(),
+ allocation_site);
+ if (FLAG_allocation_site_pretenuring) {
+ HValue* memento_create_count = Add<HLoadNamedField>(
+ allocation_site, HObjectAccess::ForAllocationSiteOffset(
+ AllocationSite::kMementoCreateCountOffset));
+ memento_create_count = AddUncasted<HAdd>(
+ memento_create_count, graph()->GetConstant1());
+ HStoreNamedField* store = Add<HStoreNamedField>(
+ allocation_site, HObjectAccess::ForAllocationSiteOffset(
+ AllocationSite::kMementoCreateCountOffset), memento_create_count);
+ // No write barrier needed to store a smi.
+ store->SkipWriteBarrier();
+ }
}
Handle<Type> type,
HIfContinuation* continuation);
- HValue* BuildCreateAllocationMemento(HValue* previous_object,
- int previous_object_size,
- HValue* payload);
+ void BuildCreateAllocationMemento(HValue* previous_object,
+ HValue* previous_object_size,
+ HValue* payload);
HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
CompilationInfo* info);
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
- __ lea(result, Operand(base, instr->offset()));
+ if (instr->offset()->IsConstantOperand()) {
+ LConstantOperand* offset = LConstantOperand::cast(instr->offset());
+ __ lea(result, Operand(base, ToInteger32(offset)));
+ } else {
+ Register offset = ToRegister(instr->offset());
+ __ lea(result, Operand(base, offset, times_1, 0));
+ }
}
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
- stream->Add(" + %d", offset());
+ stream->Add(" + ");
+ offset()->PrintTo(stream);
}
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
- HInnerAllocatedObject* inner_object) {
- LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
- LInnerAllocatedObject* result =
- new(zone()) LInnerAllocatedObject(base_object);
- return DefineAsRegister(result);
+ HInnerAllocatedObject* instr) {
+ LOperand* base_object = UseRegisterAtStart(instr->base_object());
+ LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
+ return DefineAsRegister(
+ new(zone()) LInnerAllocatedObject(base_object, offset));
}
};
-class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 2, 0> {
public:
- explicit LInnerAllocatedObject(LOperand* base_object) {
+ LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
inputs_[0] = base_object;
+ inputs_[1] = offset;
}
- LOperand* base_object() { return inputs_[0]; }
- int offset() { return hydrogen()->offset(); }
+ LOperand* base_object() const { return inputs_[0]; }
+ LOperand* offset() const { return inputs_[1]; }
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
- DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+ DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
};
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
- __ lea(result, Operand(base, instr->offset()));
+ if (instr->offset()->IsConstantOperand()) {
+ LConstantOperand* offset = LConstantOperand::cast(instr->offset());
+ __ lea(result, Operand(base, ToInteger32(offset)));
+ } else {
+ Register offset = ToRegister(instr->offset());
+ __ lea(result, Operand(base, offset, times_1, 0));
+ }
}
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
- stream->Add(" + %d", offset());
+ stream->Add(" + ");
+ offset()->PrintTo(stream);
}
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
- HInnerAllocatedObject* inner_object) {
- LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
- LInnerAllocatedObject* result =
- new(zone()) LInnerAllocatedObject(base_object);
- return DefineAsRegister(result);
+ HInnerAllocatedObject* instr) {
+ LOperand* base_object = UseRegisterAtStart(instr->base_object());
+ LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
+ return DefineAsRegister(
+ new(zone()) LInnerAllocatedObject(base_object, offset));
}
};
-class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 2, 0> {
public:
- explicit LInnerAllocatedObject(LOperand* base_object) {
+ LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
inputs_[0] = base_object;
+ inputs_[1] = offset;
}
- LOperand* base_object() { return inputs_[0]; }
- int offset() { return hydrogen()->offset(); }
+ LOperand* base_object() const { return inputs_[0]; }
+ LOperand* offset() const { return inputs_[1]; }
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
- DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+ DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
};