Commit 4d7375ca authored by hpayer@chromium.org's avatar hpayer@chromium.org

Clear next map word when folding allocations into js arrays.

BUG=
R=mstarzinger@chromium.org, mvstanton@chromium.org

Review URL: https://codereview.chromium.org/22915007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16381 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 50f3a993
......@@ -4971,7 +4971,7 @@ MaybeObject* Heap::CopyJSObjectWithAllocationSite(
int object_size = map->instance_size();
Object* clone;
ASSERT(map->CanTrackAllocationSite());
ASSERT(AllocationSite::CanTrack(map->instance_type()));
ASSERT(map->instance_type() == JS_ARRAY_TYPE);
WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
......
......@@ -3283,8 +3283,9 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
// First update the size of the dominator allocate instruction.
dominator_size = dominator_allocate->size();
int32_t dominator_size_constant =
int32_t original_object_size =
HConstant::cast(dominator_size)->GetInteger32Constant();
int32_t dominator_size_constant = original_object_size;
int32_t current_size_constant =
HConstant::cast(current_size)->GetInteger32Constant();
int32_t new_dominator_size = dominator_size_constant + current_size_constant;
......@@ -3319,9 +3320,19 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
#ifdef VERIFY_HEAP
if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
dominator_allocate->MakePrefillWithFiller();
} else {
// TODO(hpayer): This is a short-term hack to make allocation mementos
// work again in new space.
ClearNextMapWord(original_object_size);
}
#else
// TODO(hpayer): This is a short-term hack to make allocation mementos
// work again in new space.
ClearNextMapWord(original_object_size);
#endif
dominator_allocate->clear_next_map_word_ = clear_next_map_word_;
// After that replace the dominated allocate instruction.
HInstruction* dominated_allocate_instr =
HInnerAllocatedObject::New(zone,
......@@ -3457,6 +3468,19 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
}
void HAllocate::ClearNextMapWord(int offset) {
if (clear_next_map_word_) {
Zone* zone = block()->zone();
HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
HStoreNamedField* clear_next_map =
HStoreNamedField::New(zone, context(), this, access,
block()->graph()->GetConstantNull());
clear_next_map->ClearAllSideEffects();
clear_next_map->InsertAfter(this);
}
}
void HAllocate::PrintDataTo(StringStream* stream) {
size()->PrintNameTo(stream);
stream->Add(" (");
......
......@@ -5166,7 +5166,8 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
InstanceType instance_type)
: HTemplateInstruction<2>(type),
dominating_allocate_(NULL),
filler_free_space_size_(NULL) {
filler_free_space_size_(NULL),
clear_next_map_word_(false) {
SetOperandAt(0, context);
SetOperandAt(1, size);
set_representation(Representation::Tagged());
......@@ -5188,6 +5189,8 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
}
clear_next_map_word_ = pretenure_flag == NOT_TENURED &&
AllocationSite::CanTrack(instance_type);
}
void UpdateSize(HValue* size) {
......@@ -5207,10 +5210,13 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
allocate->IsOldPointerSpaceAllocation());
}
void ClearNextMapWord(int offset);
Flags flags_;
Handle<Map> known_initial_map_;
HAllocate* dominating_allocate_;
HStoreNamedField* filler_free_space_size_;
bool clear_next_map_word_;
};
......
......@@ -8329,7 +8329,7 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
int* data_offset,
AllocationSiteMode mode) {
bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
boilerplate_object->map()->CanTrackAllocationSite();
AllocationSite::CanTrack(boilerplate_object->map()->instance_type());
// If using allocation sites, then the payload on the site should already
// be filled in as a valid (boilerplate) array.
......@@ -8385,7 +8385,7 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
// Create allocation site info.
if (mode == TRACK_ALLOCATION_SITE &&
boilerplate_object->map()->CanTrackAllocationSite()) {
AllocationSite::CanTrack(boilerplate_object->map()->instance_type())) {
elements_offset += AllocationMemento::kSize;
*offset += AllocationMemento::kSize;
BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
......
......@@ -1312,7 +1312,7 @@ void JSObject::ValidateElements() {
bool JSObject::ShouldTrackAllocationInfo() {
if (map()->CanTrackAllocationSite()) {
if (AllocationSite::CanTrack(map()->instance_type())) {
if (!IsJSArray()) {
return true;
}
......@@ -1349,6 +1349,11 @@ AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
}
inline bool AllocationSite::CanTrack(InstanceType type) {
return type == JS_ARRAY_TYPE;
}
MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
ValidateElements();
ElementsKind elements_kind = map()->elements_kind();
......@@ -3593,11 +3598,6 @@ Code::Flags Code::flags() {
}
inline bool Map::CanTrackAllocationSite() {
return instance_type() == JS_ARRAY_TYPE;
}
void Map::set_owns_descriptors(bool is_shared) {
set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
}
......
......@@ -5776,7 +5776,6 @@ class Map: public HeapObject {
set_bit_field3(EnumLengthBits::update(bit_field3(), length));
}
inline bool CanTrackAllocationSite();
inline bool owns_descriptors();
inline void set_owns_descriptors(bool is_shared);
inline bool is_observed();
......@@ -7845,6 +7844,7 @@ class AllocationSite: public Struct {
static inline AllocationSiteMode GetMode(
ElementsKind boilerplate_elements_kind);
static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
static inline bool CanTrack(InstanceType type);
static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
static const int kWeakNextOffset = kTransitionInfoOffset + kPointerSize;
......
......@@ -56,7 +56,7 @@ function doubles() {
doubles(); doubles(); doubles();
%OptimizeFunctionOnNextCall(doubles);
var result = doubles();
result = doubles();
gc();
......@@ -72,8 +72,31 @@ function doubles_int() {
doubles_int(); doubles_int(); doubles_int();
%OptimizeFunctionOnNextCall(doubles_int);
var result = doubles_int();
result = doubles_int();
gc();
assertEquals(result[1], 3.1);
// Test allocation folding over a branch.
function branch_int(left) {
var elem1 = [1, 2];
var elem2;
if (left) {
elem2 = [3, 4];
} else {
elem2 = [5, 6];
}
return elem2;
}
branch_int(1); branch_int(1); branch_int(1);
%OptimizeFunctionOnNextCall(branch_int);
result = branch_int(1);
var result2 = branch_int(0);
gc();
assertEquals(result[1], 4);
assertEquals(result2[1], 6);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment