Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Unified Diff: src/hydrogen.cc

Issue 11299004: Use the property load IC for accessing the array length. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added comments. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 51ae7f5a44c29fc4b69f66651b95fcfef7a6f2fa..9edd440b4f0601bbabf1da9e765bf1b19d50a956 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -6613,6 +6613,8 @@ void HGraphBuilder::VisitProperty(Property* expr) {
HInstruction* instr = NULL;
if (expr->AsProperty()->IsArrayLength()) {
+ // Note that in the monomorphic case IsArrayLength() is false because we
+ // handle that it with a regular property load IC.
HValue* array = Pop();
AddInstruction(new(zone()) HCheckNonSmi(array));
HInstruction* mapcheck =
@@ -6648,23 +6650,74 @@ void HGraphBuilder::VisitProperty(Property* expr) {
map = types->first();
if (map->is_dictionary_map()) monomorphic = false;
}
- if (monomorphic) {
- Handle<JSFunction> getter;
- Handle<JSObject> holder;
- if (LookupGetter(map, name, &getter, &holder)) {
- AddCheckConstantFunction(holder, Top(), map);
- if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
- AddInstruction(new(zone()) HPushArgument(Pop()));
- instr = new(zone()) HCallConstantFunction(getter, 1);
+
+ // Try to see if this is an array length access.
+ if (name->Equals(isolate()->heap()->length_symbol())) {
+ bool is_array = false;
+ bool fast_mode = false;
+ bool map_mode = false;
+ HInstruction* mapcheck = NULL;
+
+ if (expr->IsMonomorphic()) {
+ // Even if there is more than one map they all must be element
+ // transition maps, so checking just one is ok.
+ if (map->instance_type() == JS_ARRAY_TYPE) {
+ is_array = true;
+ map_mode = true;
+ fast_mode = IsFastElementsKind(map->elements_kind());
+ }
} else {
- instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
+ // Since we will emit an instance check we have to conservatively
+ // assume that some arrays will contain slow elements, so we set
+ // fast_mode to false.
+ map_mode = false;
+ fast_mode = false;
+ is_array = true;
+ for (int i = 0; i < types->length(); i++) {
+ Handle<Map> current_map = types->at(i);
+ if (!current_map->instance_type() == JS_ARRAY_TYPE) {
+ is_array = false;
+ break;
+ }
+ }
+ }
+
+ // It is an array length access so we produce a HJSArrayLength.
+ if (is_array) {
+ HValue* array = Pop();
+ AddInstruction(new(zone()) HCheckNonSmi(array));
+ mapcheck = map_mode ?
+ HInstruction::cast(
+ new(zone()) HCheckMaps(array, map, zone(), NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS)) :
+ HInstruction::cast(
+ HCheckInstanceType::NewIsJSArray(array, zone()));
+ AddInstruction(mapcheck);
+ instr = new(zone()) HJSArrayLength(
+ array, mapcheck, fast_mode ? HType::Smi() : HType::Tagged());
}
- } else if (types != NULL && types->length() > 1) {
- return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
- } else {
- instr = BuildLoadNamedGeneric(Pop(), name, expr);
}
+ // We cannot know if it was an array length access so we handle it as
+ // a regular property access.
+ if (instr == NULL) {
+ if (monomorphic) {
+ Handle<JSFunction> getter;
+ Handle<JSObject> holder;
+ if (LookupGetter(map, name, &getter, &holder)) {
+ AddCheckConstantFunction(holder, Top(), map);
+ if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
+ AddInstruction(new(zone()) HPushArgument(Pop()));
+ instr = new(zone()) HCallConstantFunction(getter, 1);
+ } else {
+ instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
+ }
+ } else if (types != NULL && types->length() > 1) {
+ return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
+ } else {
+ instr = BuildLoadNamedGeneric(Pop(), name, expr);
+ }
+ }
} else {
CHECK_ALIVE(VisitForValue(expr->key()));
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698