Revision: 16260
Author: [email protected]
Date: Wed Aug 21 14:49:56 2013 UTC
Log: Pass checked values to HLoadNamedField, removing the need for
extra type-check field.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/22831003
http://code.google.com/p/v8/source/detail?r=16260
Modified:
/branches/bleeding_edge/src/code-stubs-hydrogen.cc
/branches/bleeding_edge/src/hydrogen-escape-analysis.cc
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Fri Aug 9 18:40:10
2013 UTC
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Wed Aug 21 14:49:56
2013 UTC
@@ -352,7 +352,7 @@
HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site,
access);
if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
- HValue* elements = AddLoadElements(boilerplate, NULL);
+ HValue* elements = AddLoadElements(boilerplate);
IfBuilder if_fixed_cow(this);
if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
@@ -513,7 +513,7 @@
HObjectAccess access = casted_stub()->is_inobject() ?
HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
- return AddInstruction(BuildLoadNamedField(GetParameter(0), access,
NULL));
+ return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
}
@@ -528,7 +528,7 @@
HObjectAccess access = casted_stub()->is_inobject() ?
HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
- return AddInstruction(BuildLoadNamedField(GetParameter(0), access,
NULL));
+ return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Mon Aug 12
09:26:18 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 21
14:49:56 2013 UTC
@@ -215,7 +215,6 @@
for (HUseIterator it(mapcheck->uses()); !it.Done();
it.Advance()) {
if (!it.value()->IsLoadNamedField()) continue;
HLoadNamedField* load = HLoadNamedField::cast(it.value());
- ASSERT(load->typecheck() == mapcheck);
load->ClearTypeCheck();
}
ASSERT(mapcheck->HasNoUses());
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Aug 19
10:55:51 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 21
14:49:56 2013 UTC
@@ -2849,10 +2849,6 @@
void HLoadNamedField::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
access_.PrintTo(stream);
- if (HasTypeCheck()) {
- stream->Add(" ");
- typecheck()->PrintNameTo(stream);
- }
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Aug 20 11:10:24
2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 21 14:49:56
2013 UTC
@@ -1370,6 +1370,9 @@
}
DECLARE_CONCRETE_INSTRUCTION(CompareMap)
+
+ protected:
+ virtual int RedefinedOperandIndex() { return 0; }
private:
Handle<Map> map_;
@@ -2574,6 +2577,8 @@
}
return true;
}
+
+ virtual int RedefinedOperandIndex() { return 0; }
private:
void Add(Handle<Map> map, Zone* zone) {
@@ -2698,6 +2703,8 @@
HCheckInstanceType* b = HCheckInstanceType::cast(other);
return check_ == b->check_;
}
+
+ virtual int RedefinedOperandIndex() { return 0; }
private:
enum Check {
@@ -5585,20 +5592,13 @@
};
-class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
+class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> {
public:
DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess);
- DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess,
- HValue*);
HValue* object() { return OperandAt(0); }
- HValue* typecheck() {
- ASSERT(HasTypeCheck());
- return OperandAt(1);
- }
-
- bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
- void ClearTypeCheck() { SetOperandAt(1, object()); }
+ bool HasTypeCheck() { return object()->IsCheckMaps(); }
+ void ClearTypeCheck() { SetOperandAt(0, object()->ActualValue()); }
HObjectAccess access() const { return access_; }
Representation field_representation() const {
return access_.representation();
@@ -5624,13 +5624,9 @@
}
private:
- HLoadNamedField(HValue* object,
- HObjectAccess access,
- HValue* typecheck = NULL)
- : access_(access) {
+ HLoadNamedField(HValue* object, HObjectAccess access) : access_(access) {
ASSERT(object != NULL);
SetOperandAt(0, object);
- SetOperandAt(1, typecheck != NULL ? typecheck : object);
Representation representation = access.representation();
if (representation.IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Tue Aug 20 11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Aug 21 14:49:56 2013 UTC
@@ -1191,7 +1191,7 @@
}
if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
- HInstruction* elements = AddLoadElements(object, NULL);
+ HInstruction* elements = AddLoadElements(object);
HInstruction* empty_fixed_array = Add<HConstant>(
isolate()->factory()->empty_fixed_array());
@@ -1222,7 +1222,7 @@
HValue* object,
HValue* key,
HValue* val,
- HCheckMaps* mapcheck,
+ HCheckMaps* checked_object,
bool is_js_array,
ElementsKind elements_kind,
bool is_store,
@@ -1237,13 +1237,14 @@
// generated store code.
if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
(elements_kind == FAST_ELEMENTS && is_store)) {
- if (mapcheck != NULL) {
- mapcheck->ClearGVNFlag(kDependsOnElementsKind);
+ if (checked_object != NULL) {
+ checked_object->ClearGVNFlag(kDependsOnElementsKind);
}
}
+ if (checked_object != NULL) object = checked_object;
bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
bool fast_elements = IsFastObjectElementsKind(elements_kind);
- HValue* elements = AddLoadElements(object, mapcheck);
+ HValue* elements = AddLoadElements(object);
if (is_store && (fast_elements || fast_smi_only_elements) &&
store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
HCheckMaps* check_cow_map = Add<HCheckMaps>(
@@ -1252,8 +1253,8 @@
}
HInstruction* length = NULL;
if (is_js_array) {
- length = Add<HLoadNamedField>(object,
- HObjectAccess::ForArrayLength(elements_kind), mapcheck);
+ length = Add<HLoadNamedField>(
+ object, HObjectAccess::ForArrayLength(elements_kind));
} else {
length = AddLoadFixedArrayLength(elements);
}
@@ -1283,7 +1284,7 @@
Add<HLoadExternalArrayPointer>(elements);
return AddExternalArrayElementAccess(
external_elements, checked_key, val,
- mapcheck, elements_kind, is_store);
+ checked_object, elements_kind, is_store);
}
}
ASSERT(fast_smi_only_elements ||
@@ -1320,7 +1321,7 @@
}
}
}
- return AddFastElementAccess(elements, checked_key, val, mapcheck,
+ return AddFastElementAccess(elements, checked_key, val, checked_object,
elements_kind, is_store, load_mode,
store_mode);
}
@@ -1493,11 +1494,8 @@
}
-HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
- HValue* typecheck) {
- return Add<HLoadNamedField>(object,
- HObjectAccess::ForElementsPointer(),
- typecheck);
+HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) {
+ return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer());
}
@@ -1713,7 +1711,7 @@
if (length > 0) {
// Get hold of the elements array of the boilerplate and setup the
// elements pointer in the resulting object.
- HValue* boilerplate_elements = AddLoadElements(boilerplate, NULL);
+ HValue* boilerplate_elements = AddLoadElements(boilerplate);
HValue* object_elements = Add<HInnerAllocatedObject>(object,
elems_offset);
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
object_elements);
@@ -1846,7 +1844,7 @@
// map, because we can just load the map in that case.
HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
return builder()->AddInstruction(
- builder()->BuildLoadNamedField(constructor_function_, access,
NULL));
+ builder()->BuildLoadNamedField(constructor_function_, access));
}
HInstruction* native_context = builder()->BuildGetNativeContext();
@@ -1867,7 +1865,7 @@
// Find the map near the constructor function
HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
return builder()->AddInstruction(
- builder()->BuildLoadNamedField(constructor_function_, access, NULL));
+ builder()->BuildLoadNamedField(constructor_function_, access));
}
@@ -4312,7 +4310,6 @@
int data_size = 0;
int pointer_size = 0;
int max_properties = kMaxFastLiteralProperties;
- HCheckMaps* type_check = NULL;
if (IsFastLiteral(original_boilerplate_object,
kMaxFastLiteralDepth,
&max_properties,
@@ -4350,7 +4347,7 @@
// De-opt if elements kind changed from boilerplate_elements_kind.
Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
isolate());
- type_check = Add<HCheckMaps>(literal, map, top_info());
+ literal = Add<HCheckMaps>(literal, map, top_info());
}
// The array is expected in the bailout environment during computation
@@ -4371,7 +4368,7 @@
HValue* value = Pop();
if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);
- elements = AddLoadElements(literal, type_check);
+ elements = AddLoadElements(literal);
HValue* key = Add<HConstant>(i);
@@ -4594,8 +4591,8 @@
if (count == types->length()) {
// Everything matched; can use monomorphic load.
BuildCheckHeapObject(object);
- HCheckMaps* type_check = Add<HCheckMaps>(object, types);
- return BuildLoadNamedField(object, access, type_check);
+ HCheckMaps* checked_object = Add<HCheckMaps>(object, types);
+ return BuildLoadNamedField(checked_object, access);
}
if (count != 0) return NULL;
@@ -4616,14 +4613,14 @@
if (!lookup.IsField()) return NULL;
BuildCheckHeapObject(object);
- HCheckMaps* type_check = Add<HCheckMaps>(object, types);
+ Add<HCheckMaps>(object, types);
Handle<JSObject> holder(lookup.holder());
Handle<Map> holder_map(holder->map());
- BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder);
- HValue* holder_value = Add<HConstant>(holder);
- return BuildLoadNamedField(holder_value,
- HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+ HValue* checked_holder = BuildCheckPrototypeMaps(
+ Handle<JSObject>::cast(prototype), holder);
+ return BuildLoadNamedField(checked_holder,
+ HObjectAccess::ForField(holder_map, &lookup, name));
}
@@ -4698,7 +4695,7 @@
// TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic.
if (lookup.IsField()) {
HObjectAccess access = HObjectAccess::ForField(map, &lookup, name);
- HLoadNamedField* load = BuildLoadNamedField(object, access,
compare);
+ HLoadNamedField* load = BuildLoadNamedField(compare, access);
load->set_position(expr->position());
AddInstruction(load);
if (!ast_context()->IsEffect()) Push(load);
@@ -5371,32 +5368,29 @@
HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
- HObjectAccess access,
- HValue* typecheck) {
+ HObjectAccess access) {
if (FLAG_track_double_fields && access.representation().IsDouble()) {
// load the heap number
HLoadNamedField* heap_number = Add<HLoadNamedField>(
object, access.WithRepresentation(Representation::Tagged()));
heap_number->set_type(HType::HeapNumber());
// load the double value from it
- return New<HLoadNamedField>(heap_number,
- HObjectAccess::ForHeapNumberValue(),
- typecheck);
+ return New<HLoadNamedField>(
+ heap_number, HObjectAccess::ForHeapNumberValue());
}
- return New<HLoadNamedField>(object, access, typecheck);
+ return New<HLoadNamedField>(object, access);
}
HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
- HValue* typecheck) {
+ HValue* checked_string)
{
if (FLAG_fold_constants && object->IsConstant()) {
HConstant* constant = HConstant::cast(object);
if (constant->HasStringValue()) {
return New<HConstant>(constant->StringValue()->length());
}
}
- return BuildLoadNamedField(
- object, HObjectAccess::ForStringLength(), typecheck);
+ return BuildLoadNamedField(checked_string,
HObjectAccess::ForStringLength());
}
@@ -5435,18 +5429,18 @@
// Handle access to various length properties
if (name->Equals(isolate()->heap()->length_string())) {
if (map->instance_type() == JS_ARRAY_TYPE) {
- HCheckMaps* type_check = AddCheckMap(object, map);
- return New<HLoadNamedField>(object,
- HObjectAccess::ForArrayLength(map->elements_kind()), type_check);
+ HCheckMaps* checked_object = AddCheckMap(object, map);
+ return New<HLoadNamedField>(
+ checked_object,
HObjectAccess::ForArrayLength(map->elements_kind()));
}
}
LookupResult lookup(isolate());
map->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsField()) {
- HCheckMaps* type_check = AddCheckMap(object, map);
- return BuildLoadNamedField(object,
- HObjectAccess::ForField(map, &lookup, name), type_check);
+ HCheckMaps* checked_object = AddCheckMap(object, map);
+ return BuildLoadNamedField(
+ checked_object, HObjectAccess::ForField(map, &lookup, name));
}
// Handle a load of a constant known function.
@@ -5462,11 +5456,10 @@
Handle<JSObject> prototype(JSObject::cast(map->prototype()));
Handle<JSObject> holder(lookup.holder());
Handle<Map> holder_map(holder->map());
- HCheckMaps* type_check = AddCheckMap(object, map);
- BuildCheckPrototypeMaps(prototype, holder);
- HValue* holder_value = Add<HConstant>(holder);
- return BuildLoadNamedField(holder_value,
- HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+ AddCheckMap(object, map);
+ HValue* checked_holder = BuildCheckPrototypeMaps(prototype, holder);
+ return BuildLoadNamedField(
+ checked_holder, HObjectAccess::ForField(holder_map, &lookup,
name));
}
// Handle a load of a constant function somewhere in the prototype chain.
@@ -5659,11 +5652,11 @@
return is_store ? NULL : instr;
}
- HInstruction* checkspec =
+ HInstruction* checked_object =
AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
HBasicBlock* join = graph()->CreateBasicBlock();
- HInstruction* elements = AddLoadElements(object, checkspec);
+ HInstruction* elements = AddLoadElements(checked_object);
for (int i = 0; i < untransitionable_maps.length(); ++i) {
Handle<Map> map = untransitionable_maps[i];
@@ -5685,7 +5678,7 @@
}
if (map->instance_type() == JS_ARRAY_TYPE) {
HInstruction* length = Add<HLoadNamedField>(
- object, HObjectAccess::ForArrayLength(elements_kind),
mapcompare);
+ mapcompare, HObjectAccess::ForArrayLength(elements_kind));
checked_key = Add<HBoundsCheck>(key, length);
} else {
HInstruction* length = AddLoadFixedArrayLength(elements);
@@ -5961,30 +5954,34 @@
}
-void HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
- CompilationInfo* info) {
+HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject>
constant,
+ CompilationInfo* info) {
HConstant* constant_value = New<HConstant>(constant);
if (constant->map()->CanOmitMapChecks()) {
constant->map()->AddDependentCompilationInfo(
DependentCode::kPrototypeCheckGroup, info);
- return;
+ return constant_value;
}
AddInstruction(constant_value);
HCheckMaps* check =
Add<HCheckMaps>(constant_value, handle(constant->map()), info);
check->ClearGVNFlag(kDependsOnElementsKind);
+ return check;
}
-void HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
- Handle<JSObject> holder) {
- BuildConstantMapCheck(prototype, top_info());
+HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject>
prototype,
+ Handle<JSObject>
holder) {
while (!prototype.is_identical_to(holder)) {
+ BuildConstantMapCheck(prototype, top_info());
prototype = handle(JSObject::cast(prototype->GetPrototype()));
- BuildConstantMapCheck(prototype, top_info());
}
+
+ HInstruction* checked_object = BuildConstantMapCheck(prototype,
top_info());
+ if (!checked_object->IsLinked()) AddInstruction(checked_object);
+ return checked_object;
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Tue Aug 20 11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.h Wed Aug 21 14:49:56 2013 UTC
@@ -1257,13 +1257,10 @@
LoadKeyedHoleMode load_mode,
KeyedAccessStoreMode store_mode);
- HLoadNamedField* BuildLoadNamedField(
- HValue* object,
- HObjectAccess access,
- HValue* typecheck);
- HInstruction* BuildLoadStringLength(HValue* object, HValue* typecheck);
- HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>);
- HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck);
+ HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess
access);
+ HInstruction* BuildLoadStringLength(HValue* object, HValue*
checked_value);
+ HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map>);
+ HLoadNamedField* AddLoadElements(HValue* object);
HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
@@ -1549,9 +1546,10 @@
int previous_object_size,
HValue* payload);
- void BuildConstantMapCheck(Handle<JSObject> constant, CompilationInfo*
info);
- void BuildCheckPrototypeMaps(Handle<JSObject> prototype,
- Handle<JSObject> holder);
+ HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
+ CompilationInfo* info);
+ HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
+ Handle<JSObject> holder);
HInstruction* BuildGetNativeContext();
HInstruction* BuildGetArrayFunction();
@@ -1602,22 +1600,6 @@
AddInstruction(instr);
return instr;
}
-
-
-template<>
-inline HInstruction* HGraphBuilder::NewUncasted<HLoadNamedField>(
- HValue* object, HObjectAccess access) {
- return NewUncasted<HLoadNamedField>(object, access,
- static_cast<HValue*>(NULL));
-}
-
-
-template<>
-inline HInstruction* HGraphBuilder::AddUncasted<HLoadNamedField>(
- HValue* object, HObjectAccess access) {
- return AddUncasted<HLoadNamedField>(object, access,
- static_cast<HValue*>(NULL));
-}
template<>
--
--
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.