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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 6595 matching lines...) Expand 10 before | Expand all | Expand 10 after
6606 ASSERT(current_block() != NULL); 6606 ASSERT(current_block() != NULL);
6607 ASSERT(current_block()->HasPredecessor()); 6607 ASSERT(current_block()->HasPredecessor());
6608 expr->RecordTypeFeedback(oracle(), zone()); 6608 expr->RecordTypeFeedback(oracle(), zone());
6609 6609
6610 if (TryArgumentsAccess(expr)) return; 6610 if (TryArgumentsAccess(expr)) return;
6611 6611
6612 CHECK_ALIVE(VisitForValue(expr->obj())); 6612 CHECK_ALIVE(VisitForValue(expr->obj()));
6613 6613
6614 HInstruction* instr = NULL; 6614 HInstruction* instr = NULL;
6615 if (expr->AsProperty()->IsArrayLength()) { 6615 if (expr->AsProperty()->IsArrayLength()) {
6616 // Note that in the monomorphic case IsArrayLength() is false because we
6617 // handle that it with a regular property load IC.
6616 HValue* array = Pop(); 6618 HValue* array = Pop();
6617 AddInstruction(new(zone()) HCheckNonSmi(array)); 6619 AddInstruction(new(zone()) HCheckNonSmi(array));
6618 HInstruction* mapcheck = 6620 HInstruction* mapcheck =
6619 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); 6621 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone()));
6620 instr = new(zone()) HJSArrayLength(array, mapcheck); 6622 instr = new(zone()) HJSArrayLength(array, mapcheck);
6621 } else if (expr->IsStringLength()) { 6623 } else if (expr->IsStringLength()) {
6622 HValue* string = Pop(); 6624 HValue* string = Pop();
6623 AddInstruction(new(zone()) HCheckNonSmi(string)); 6625 AddInstruction(new(zone()) HCheckNonSmi(string));
6624 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 6626 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
6625 instr = new(zone()) HStringLength(string); 6627 instr = new(zone()) HStringLength(string);
(...skipping 15 matching lines...) Expand all
6641 } else if (expr->key()->IsPropertyName()) { 6643 } else if (expr->key()->IsPropertyName()) {
6642 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 6644 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
6643 SmallMapList* types = expr->GetReceiverTypes(); 6645 SmallMapList* types = expr->GetReceiverTypes();
6644 6646
6645 bool monomorphic = expr->IsMonomorphic(); 6647 bool monomorphic = expr->IsMonomorphic();
6646 Handle<Map> map; 6648 Handle<Map> map;
6647 if (expr->IsMonomorphic()) { 6649 if (expr->IsMonomorphic()) {
6648 map = types->first(); 6650 map = types->first();
6649 if (map->is_dictionary_map()) monomorphic = false; 6651 if (map->is_dictionary_map()) monomorphic = false;
6650 } 6652 }
6651 if (monomorphic) { 6653
6652 Handle<JSFunction> getter; 6654 // Try to see if this is an array length access.
6653 Handle<JSObject> holder; 6655 if (name->Equals(isolate()->heap()->length_symbol())) {
6654 if (LookupGetter(map, name, &getter, &holder)) { 6656 bool is_array = false;
6655 AddCheckConstantFunction(holder, Top(), map); 6657 bool fast_mode = false;
6656 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; 6658 bool map_mode = false;
6657 AddInstruction(new(zone()) HPushArgument(Pop())); 6659 HInstruction* mapcheck = NULL;
6658 instr = new(zone()) HCallConstantFunction(getter, 1); 6660
6661 if (expr->IsMonomorphic()) {
6662 // Even if there is more than one map they all must be element
6663 // transition maps, so checking just one is ok.
6664 if (map->instance_type() == JS_ARRAY_TYPE) {
6665 is_array = true;
6666 map_mode = true;
6667 fast_mode = IsFastElementsKind(map->elements_kind());
6668 }
6659 } else { 6669 } else {
6660 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); 6670 // Since we will emit an instance check we have to conservatively
6671 // assume that some arrays will contain slow elements, so we set
6672 // fast_mode to false.
6673 map_mode = false;
6674 fast_mode = false;
6675 is_array = true;
6676 for (int i = 0; i < types->length(); i++) {
6677 Handle<Map> current_map = types->at(i);
6678 if (!current_map->instance_type() == JS_ARRAY_TYPE) {
6679 is_array = false;
6680 break;
6681 }
6682 }
6661 } 6683 }
6662 } else if (types != NULL && types->length() > 1) { 6684
6663 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); 6685 // It is an array length access so we produce a HJSArrayLength.
6664 } else { 6686 if (is_array) {
6665 instr = BuildLoadNamedGeneric(Pop(), name, expr); 6687 HValue* array = Pop();
6688 AddInstruction(new(zone()) HCheckNonSmi(array));
6689 mapcheck = map_mode ?
6690 HInstruction::cast(
6691 new(zone()) HCheckMaps(array, map, zone(), NULL,
6692 ALLOW_ELEMENT_TRANSITION_MAPS)) :
6693 HInstruction::cast(
6694 HCheckInstanceType::NewIsJSArray(array, zone()));
6695 AddInstruction(mapcheck);
6696 instr = new(zone()) HJSArrayLength(
6697 array, mapcheck, fast_mode ? HType::Smi() : HType::Tagged());
6698 }
6666 } 6699 }
6667 6700
6701 // We cannot know if it was an array length access so we handle it as
6702 // a regular property access.
6703 if (instr == NULL) {
6704 if (monomorphic) {
6705 Handle<JSFunction> getter;
6706 Handle<JSObject> holder;
6707 if (LookupGetter(map, name, &getter, &holder)) {
6708 AddCheckConstantFunction(holder, Top(), map);
6709 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
6710 AddInstruction(new(zone()) HPushArgument(Pop()));
6711 instr = new(zone()) HCallConstantFunction(getter, 1);
6712 } else {
6713 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
6714 }
6715 } else if (types != NULL && types->length() > 1) {
6716 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name);
6717 } else {
6718 instr = BuildLoadNamedGeneric(Pop(), name, expr);
6719 }
6720 }
6668 } else { 6721 } else {
6669 CHECK_ALIVE(VisitForValue(expr->key())); 6722 CHECK_ALIVE(VisitForValue(expr->key()));
6670 6723
6671 HValue* key = Pop(); 6724 HValue* key = Pop();
6672 HValue* obj = Pop(); 6725 HValue* obj = Pop();
6673 6726
6674 bool has_side_effects = false; 6727 bool has_side_effects = false;
6675 HValue* load = HandleKeyedElementAccess( 6728 HValue* load = HandleKeyedElementAccess(
6676 obj, key, NULL, expr, expr->id(), expr->position(), 6729 obj, key, NULL, expr, expr->id(), expr->position(),
6677 false, // is_store 6730 false, // is_store
(...skipping 3333 matching lines...) Expand 10 before | Expand all | Expand 10 after
10011 } 10064 }
10012 } 10065 }
10013 10066
10014 #ifdef DEBUG 10067 #ifdef DEBUG
10015 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10068 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10016 if (allocator_ != NULL) allocator_->Verify(); 10069 if (allocator_ != NULL) allocator_->Verify();
10017 #endif 10070 #endif
10018 } 10071 }
10019 10072
10020 } } // namespace v8::internal 10073 } } // namespace v8::internal
OLDNEW
« 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