Revision: 14625
Author: [email protected]
Date: Fri May 10 10:17:50 2013
Log: Track heap objects.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/14996004
http://code.google.com/p/v8/source/detail?r=14625
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/property-details.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Fri May 10 05:45:14 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Fri May 10 10:17:50 2013
@@ -2334,7 +2334,9 @@
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
- if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+ if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+ (FLAG_track_heap_object_fields &&
+ instr->field_representation().IsHeapObject())) {
return AssignEnvironment(result);
}
return result;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri May 10
02:52:08 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri May 10
10:17:50 2013
@@ -4229,6 +4229,12 @@
if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
DeoptimizeIf(vs, instr->environment());
}
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ Register value = ToRegister(instr->value());
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+ __ tst(value, Operand(kSmiTagMask));
+ DeoptimizeIf(eq, instr->environment());
+ }
} else if (FLAG_track_double_fields && representation.IsDouble()) {
ASSERT(transition.is_null());
ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed May 8 08:02:08
2013
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri May 10 10:17:50
2013
@@ -516,6 +516,8 @@
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_restore_name);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
Label do_store, heap_number;
__ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
@@ -685,6 +687,8 @@
ASSERT(!representation.IsNone());
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Fri May 10 02:12:52 2013
+++ /branches/bleeding_edge/src/flag-definitions.h Fri May 10 10:17:50 2013
@@ -195,7 +195,9 @@
DEFINE_bool(pretenure_literals, true, "allocate literals in old space")
DEFINE_bool(track_fields, true, "track fields with only smi values")
DEFINE_bool(track_double_fields, true, "track fields with double values")
+DEFINE_bool(track_heap_object_fields, true, "track fields with heap
values")
DEFINE_implication(track_double_fields, track_fields)
+DEFINE_implication(track_heap_object_fields, track_fields)
// Flags for data representation optimizations
DEFINE_bool(unbox_double_arrays, true, "automatically unbox arrays of
doubles")
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 10 02:52:08
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 10 10:17:50
2013
@@ -5218,6 +5218,10 @@
set_representation(Representation::Tagged());
} else if (FLAG_track_double_fields &&
field_representation.IsDouble()) {
set_representation(field_representation);
+ } else if (FLAG_track_heap_object_fields &&
+ field_representation.IsHeapObject()) {
+ set_type(HType::NonPrimitive());
+ set_representation(Representation::Tagged());
} else {
set_representation(Representation::Tagged());
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri May 10
02:52:08 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri May 10
10:17:50 2013
@@ -4239,6 +4239,19 @@
DeoptimizeIf(overflow, instr->environment());
}
}
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
+ if (IsInteger32(operand_value)) {
+ DeoptimizeIf(no_condition, instr->environment());
+ }
+ } else {
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+ Register value = ToRegister(instr->value());
+ __ test(value, Immediate(kSmiTagMask));
+ DeoptimizeIf(zero, instr->environment());
+ }
+ }
} else if (FLAG_track_double_fields && representation.IsDouble()) {
ASSERT(transition.is_null());
ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 10 05:45:14
2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 10 10:17:50
2013
@@ -2458,7 +2458,9 @@
LStoreNamedField* result =
new(zone()) LStoreNamedField(obj, val, temp, temp_map);
- if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+ if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+ (FLAG_track_heap_object_fields &&
+ instr->field_representation().IsHeapObject())) {
return AssignEnvironment(result);
}
return result;
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed May 8 08:02:08
2013
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri May 10 10:17:50
2013
@@ -826,6 +826,8 @@
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_restore_name);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
Label do_store, heap_number;
__ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow);
@@ -996,6 +998,8 @@
ASSERT(!representation.IsNone());
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Wed May 8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects-inl.h Fri May 10 10:17:50 2013
@@ -3608,6 +3608,10 @@
if (FLAG_track_double_fields && details.representation().IsDouble()) {
return true;
}
+ if (FLAG_track_heap_object_fields &&
+ details.representation().IsHeapObject()) {
+ return true;
+ }
}
return false;
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Wed May 8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects.cc Fri May 10 10:17:50 2013
@@ -2137,6 +2137,7 @@
case kSmi: return "s";
case kDouble: return "d";
case kInteger32: return "i";
+ case kHeapObject: return "h";
case kExternal: return "x";
default:
UNREACHABLE();
@@ -2499,10 +2500,10 @@
Representation
new_representation) {
Map* old_map = this;
DescriptorArray* old_descriptors = old_map->instance_descriptors();
- Representation old_reprepresentation =
+ Representation old_representation =
old_descriptors->GetDetails(modify_index).representation();
- if (old_reprepresentation.IsNone()) {
+ if (old_representation.IsNone()) {
UNREACHABLE();
old_descriptors->SetRepresentation(modify_index, new_representation);
return this;
@@ -2528,9 +2529,14 @@
Representation updated_representation =
updated_descriptors->GetDetails(modify_index).representation();
if (new_representation.fits_into(updated_representation)) {
- if (FLAG_trace_generalization) {
- PrintF("migrating to existing map %p -> %p\n",
- static_cast<void*>(this), static_cast<void*>(updated));
+ if (FLAG_trace_generalization &&
+ !(modify_index == 0 && new_representation.IsSmi())) {
+ PropertyDetails old_details =
old_descriptors->GetDetails(modify_index);
+ PrintF("migrating to existing map %p(%s) -> %p(%s)\n",
+ static_cast<void*>(this),
+ old_details.representation().Mnemonic(),
+ static_cast<void*>(updated),
+ updated_representation.Mnemonic());
}
return updated;
}
@@ -2541,10 +2547,13 @@
verbatim, valid, descriptors, old_descriptors);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
- old_reprepresentation =
+ old_representation =
new_descriptors->GetDetails(modify_index).representation();
- new_representation =
new_representation.generalize(old_reprepresentation);
- new_descriptors->SetRepresentation(modify_index, new_representation);
+ Representation updated_representation =
+ new_representation.generalize(old_representation);
+ if (!updated_representation.Equals(old_representation)) {
+ new_descriptors->SetRepresentation(modify_index,
updated_representation);
+ }
Map* split_map = root_map->FindLastMatchMap(
verbatim, descriptors, new_descriptors);
@@ -2558,10 +2567,14 @@
split_map->DeprecateTarget(
old_descriptors->GetKey(descriptor), new_descriptors);
- if (FLAG_trace_generalization) {
- PrintF("migrating to new map %p -> %p (%i steps)\n",
+ if (FLAG_trace_generalization &&
+ !(modify_index == 0 && new_representation.IsSmi())) {
+ PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n",
+ modify_index,
static_cast<void*>(this),
+ old_representation.Mnemonic(),
static_cast<void*>(new_descriptors),
+ updated_representation.Mnemonic(),
descriptors - descriptor);
}
=======================================
--- /branches/bleeding_edge/src/objects.h Wed May 8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects.h Fri May 10 10:17:50 2013
@@ -1066,6 +1066,13 @@
return Representation::Smi();
} else if (FLAG_track_double_fields && IsHeapNumber()) {
return Representation::Double();
+ } else if (FLAG_track_heap_object_fields && !IsUndefined()) {
+ // Don't track undefined as heapobject because it's also used as
temporary
+ // value for computed fields that may turn out to be Smi. That
combination
+ // will go tagged, so go tagged immediately.
+ // TODO(verwaest): Change once we track computed boilerplate fields.
+ ASSERT(IsHeapObject());
+ return Representation::HeapObject();
} else {
return Representation::Tagged();
}
@@ -1076,6 +1083,8 @@
return IsSmi();
} else if (FLAG_track_double_fields && representation.IsDouble()) {
return IsNumber();
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ return IsHeapObject();
}
return true;
}
=======================================
--- /branches/bleeding_edge/src/property-details.h Wed May 8 07:18:30 2013
+++ /branches/bleeding_edge/src/property-details.h Fri May 10 10:17:50 2013
@@ -83,6 +83,7 @@
kSmi,
kInteger32,
kDouble,
+ kHeapObject,
kTagged,
kExternal,
kNumRepresentations
@@ -95,6 +96,7 @@
static Representation Smi() { return Representation(kSmi); }
static Representation Integer32() { return Representation(kInteger32); }
static Representation Double() { return Representation(kDouble); }
+ static Representation HeapObject() { return Representation(kHeapObject);
}
static Representation External() { return Representation(kExternal); }
static Representation FromKind(Kind kind) { return Representation(kind);
}
@@ -111,6 +113,7 @@
bool is_more_general_than(const Representation& other) const {
ASSERT(kind_ != kExternal);
ASSERT(other.kind_ != kExternal);
+ if (IsHeapObject()) return other.IsDouble();
return kind_ > other.kind_;
}
@@ -119,11 +122,9 @@
}
Representation generalize(Representation other) {
- if (is_more_general_than(other)) {
- return *this;
- } else {
- return other;
- }
+ if (other.fits_into(*this)) return *this;
+ if (other.is_more_general_than(*this)) return other;
+ return Representation::Tagged();
}
Kind kind() const { return static_cast<Kind>(kind_); }
@@ -132,6 +133,7 @@
bool IsSmi() const { return kind_ == kSmi; }
bool IsInteger32() const { return kind_ == kInteger32; }
bool IsDouble() const { return kind_ == kDouble; }
+ bool IsHeapObject() const { return kind_ == kHeapObject; }
bool IsExternal() const { return kind_ == kExternal; }
bool IsSpecialization() const {
return kind_ == kInteger32 || kind_ == kDouble;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri May 10
02:52:08 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri May 10
10:17:50 2013
@@ -3921,6 +3921,19 @@
Register value = ToRegister(instr->value());
__ Integer32ToSmi(value, value);
}
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
+ if (IsInteger32Constant(operand_value)) {
+ DeoptimizeIf(no_condition, instr->environment());
+ }
+ } else {
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+ Register value = ToRegister(instr->value());
+ Condition cc = masm()->CheckSmi(value);
+ DeoptimizeIf(cc, instr->environment());
+ }
+ }
} else if (FLAG_track_double_fields && representation.IsDouble()) {
ASSERT(transition.is_null());
ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Fri May 10 05:45:14 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Fri May 10 10:17:50 2013
@@ -2273,7 +2273,9 @@
needs_write_barrier_for_map) ? TempRegister() : NULL;
LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
- if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+ if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+ (FLAG_track_heap_object_fields &&
+ instr->field_representation().IsHeapObject())) {
return AssignEnvironment(result);
}
return result;
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed May 8 08:02:08
2013
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Fri May 10 10:17:50
2013
@@ -807,6 +807,8 @@
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_restore_name);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
Label do_store, heap_number;
__ AllocateHeapNumber(storage_reg, scratch1, slow);
@@ -953,6 +955,8 @@
ASSERT(!representation.IsNone());
if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js
Fri Apr 26 08:30:41 2013
+++ /branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js
Fri May 10 10:17:50 2013
@@ -129,7 +129,7 @@
// upon can hoisted, too.
function testExactMapHoisting3(a) {
var object = new Object();
- a.foo = 0;
+ a.foo = null;
a[0] = 0;
a[1] = 1;
var count = 3;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.