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

Side by Side Diff: src/hydrogen.cc

Issue 12700006: Replace ICStub for array.length with hydrogen stub (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed debug print Created 7 years, 9 months 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
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 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck, 1045 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck,
1046 HType::Smi())); 1046 HType::Smi()));
1047 } else { 1047 } else {
1048 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 1048 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
1049 } 1049 }
1050 checked_key = AddBoundsCheck( 1050 checked_key = AddBoundsCheck(
1051 key, length, ALLOW_SMI_KEY, checked_index_representation); 1051 key, length, ALLOW_SMI_KEY, checked_index_representation);
1052 return BuildFastElementAccess(elements, checked_key, val, mapcheck, 1052 return BuildFastElementAccess(elements, checked_key, val, mapcheck,
1053 elements_kind, is_store); 1053 elements_kind, is_store);
1054 } 1054 }
1055 1055
danno 2013/03/22 14:25:40 nit: two spaces before function
1056 HInstruction* HGraphBuilder::BuildFastArrayLengthLoad(HValue* object,
1057 HValue* typecheck) {
1058 Zone* zone = this->zone();
1059 return new (zone) HJSArrayLength(object, typecheck, HType::Smi());
1060 }
1061
1056 1062
1057 HValue* HGraphBuilder::BuildAllocateElements(HContext* context, 1063 HValue* HGraphBuilder::BuildAllocateElements(HContext* context,
1058 ElementsKind kind, 1064 ElementsKind kind,
1059 HValue* capacity) { 1065 HValue* capacity) {
1060 Zone* zone = this->zone(); 1066 Zone* zone = this->zone();
1061 1067
1062 int elements_size = IsFastDoubleElementsKind(kind) 1068 int elements_size = IsFastDoubleElementsKind(kind)
1063 ? kDoubleSize : kPointerSize; 1069 ? kDoubleSize : kPointerSize;
1064 HConstant* elements_size_value = 1070 HConstant* elements_size_value =
1065 new(zone) HConstant(elements_size, Representation::Integer32()); 1071 new(zone) HConstant(elements_size, Representation::Integer32());
(...skipping 4923 matching lines...) Expand 10 before | Expand all | Expand 10 after
5989 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); 5995 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
5990 if (lookup->IsField()) { 5996 if (lookup->IsField()) {
5991 return lookup->GetLocalFieldIndexFromMap(*type); 5997 return lookup->GetLocalFieldIndexFromMap(*type);
5992 } else { 5998 } else {
5993 Map* transition = lookup->GetTransitionMapFromMap(*type); 5999 Map* transition = lookup->GetTransitionMapFromMap(*type);
5994 return transition->PropertyIndexFor(*name) - type->inobject_properties(); 6000 return transition->PropertyIndexFor(*name) - type->inobject_properties();
5995 } 6001 }
5996 } 6002 }
5997 6003
5998 6004
6005 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
6006 AddInstruction(new(zone()) HCheckNonSmi(object));
6007 AddInstruction(new(zone()) HCheckMaps(object, map, zone()));
6008 }
6009
danno 2013/03/22 14:25:40 nit: two spaces after function
5999 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 6010 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
6000 Handle<Map> map) { 6011 Handle<Map> map) {
6001 AddInstruction(new(zone()) HCheckNonSmi(object)); 6012 AddInstruction(new(zone()) HCheckNonSmi(object));
6002 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 6013 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
6003 } 6014 }
6004 6015
6005 6016
6006 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 6017 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
6007 HValue* object, 6018 HValue* object,
6008 Handle<String> name, 6019 Handle<String> name,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
6097 Handle<Map> map) { 6108 Handle<Map> map) {
6098 // Handle a store to a known field. 6109 // Handle a store to a known field.
6099 LookupResult lookup(isolate()); 6110 LookupResult lookup(isolate());
6100 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6111 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6101 AddCheckMapsWithTransitions(object, map); 6112 AddCheckMapsWithTransitions(object, map);
6102 return BuildStoreNamedField(object, name, value, map, &lookup); 6113 return BuildStoreNamedField(object, name, value, map, &lookup);
6103 } 6114 }
6104 6115
6105 // No luck, do a generic store. 6116 // No luck, do a generic store.
6106 return BuildStoreNamedGeneric(object, name, value); 6117 return BuildStoreNamedGeneric(object, name, value);
6107 } 6118 }
danno 2013/03/22 14:25:40 nit: two spaces between functions
6108 6119
6120 bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad(
6121 Property* expr,
6122 HValue* object,
6123 SmallMapList* types,
6124 Handle<String> name) {
6125 if (!name->Equals(isolate()->heap()->length_string())) return false;
6126
6127 for (int i = 0; i < types->length(); i++) {
6128 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
6129 }
6130
6131 AddInstruction(new(zone()) HCheckNonSmi(object));
6132 HInstruction* typecheck =
6133 AddInstruction(HCheckInstanceType::NewIsJSArray(object, zone()));
6134 HInstruction* instr = BuildFastArrayLengthLoad(object, typecheck);
6135 instr->set_position(expr->position());
6136 ast_context()->ReturnInstruction(instr, expr->id());
6137 return true;
6138 }
danno 2013/03/22 14:25:40 nit: two spaces between functions.
6109 6139
6110 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 6140 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
6111 Property* expr, 6141 Property* expr,
6112 HValue* object, 6142 HValue* object,
6113 SmallMapList* types, 6143 SmallMapList* types,
6114 Handle<String> name) { 6144 Handle<String> name) {
6115 int count = 0; 6145 int count = 0;
6116 int previous_field_offset = 0; 6146 int previous_field_offset = 0;
6117 bool previous_field_is_in_object = false; 6147 bool previous_field_is_in_object = false;
6118 bool is_monomorphic_field = true; 6148 bool is_monomorphic_field = true;
6149
6150 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
6151 return;
6152
6119 Handle<Map> map; 6153 Handle<Map> map;
6120 LookupResult lookup(isolate()); 6154 LookupResult lookup(isolate());
6121 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 6155 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
6122 map = types->at(i); 6156 map = types->at(i);
6123 if (ComputeLoadStoreField(map, name, &lookup, false)) { 6157 if (ComputeLoadStoreField(map, name, &lookup, false)) {
6124 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); 6158 int index = ComputeLoadStoreFieldIndex(map, name, &lookup);
6125 bool is_in_object = index < 0; 6159 bool is_in_object = index < 0;
6126 int offset = index * kPointerSize; 6160 int offset = index * kPointerSize;
6127 if (index < 0) { 6161 if (index < 0) {
6128 // Negative property indices are in-object properties, indexed 6162 // Negative property indices are in-object properties, indexed
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
6744 } 6778 }
6745 6779
6746 6780
6747 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( 6781 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
6748 HValue* object, 6782 HValue* object,
6749 Handle<String> name, 6783 Handle<String> name,
6750 Property* expr, 6784 Property* expr,
6751 Handle<Map> map) { 6785 Handle<Map> map) {
6752 // Handle a load from a known field. 6786 // Handle a load from a known field.
6753 ASSERT(!map->is_dictionary_map()); 6787 ASSERT(!map->is_dictionary_map());
6788
6789 // Handle access to various length properties
6790 if (name->Equals(isolate()->heap()->length_string())) {
6791 if (map->instance_type() == JS_ARRAY_TYPE) {
6792 AddCheckMapsWithTransitions(object, map);
6793 return BuildFastArrayLengthLoad(object, NULL);
6794 }
6795 }
6796
6754 LookupResult lookup(isolate()); 6797 LookupResult lookup(isolate());
6755 map->LookupDescriptor(NULL, *name, &lookup); 6798 map->LookupDescriptor(NULL, *name, &lookup);
6756 if (lookup.IsField()) { 6799 if (lookup.IsField()) {
6757 AddCheckMapsWithTransitions(object, map); 6800 AddCheckMap(object, map);
6758 return BuildLoadNamedField(object, map, &lookup); 6801 return BuildLoadNamedField(object, map, &lookup);
6759 } 6802 }
6760 6803
6761 // Handle a load of a constant known function. 6804 // Handle a load of a constant known function.
6762 if (lookup.IsConstantFunction()) { 6805 if (lookup.IsConstantFunction()) {
6763 AddCheckMapsWithTransitions(object, map); 6806 AddCheckMap(object, map);
6764 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 6807 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
6765 return new(zone()) HConstant(function, Representation::Tagged()); 6808 return new(zone()) HConstant(function, Representation::Tagged());
6766 } 6809 }
6767 6810
6768 // Handle a load from a known field somewhere in the prototype chain. 6811 // Handle a load from a known field somewhere in the prototype chain.
6769 LookupInPrototypes(map, name, &lookup); 6812 LookupInPrototypes(map, name, &lookup);
6770 if (lookup.IsField()) { 6813 if (lookup.IsField()) {
6771 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6814 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6772 Handle<JSObject> holder(lookup.holder()); 6815 Handle<JSObject> holder(lookup.holder());
6773 Handle<Map> holder_map(holder->map()); 6816 Handle<Map> holder_map(holder->map());
6774 AddCheckMapsWithTransitions(object, map); 6817 AddCheckMap(object, map);
6775 HInstruction* holder_value = AddInstruction( 6818 HInstruction* holder_value = AddInstruction(
6776 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 6819 new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
6777 return BuildLoadNamedField(holder_value, holder_map, &lookup); 6820 return BuildLoadNamedField(holder_value, holder_map, &lookup);
6778 } 6821 }
6779 6822
6780 // Handle a load of a constant function somewhere in the prototype chain. 6823 // Handle a load of a constant function somewhere in the prototype chain.
6781 if (lookup.IsConstantFunction()) { 6824 if (lookup.IsConstantFunction()) {
6782 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6825 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6783 Handle<JSObject> holder(lookup.holder()); 6826 Handle<JSObject> holder(lookup.holder());
6784 Handle<Map> holder_map(holder->map()); 6827 Handle<Map> holder_map(holder->map());
6785 AddCheckMapsWithTransitions(object, map); 6828 AddCheckMap(object, map);
6786 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 6829 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
6787 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 6830 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
6788 return new(zone()) HConstant(function, Representation::Tagged()); 6831 return new(zone()) HConstant(function, Representation::Tagged());
6789 } 6832 }
6790 6833
6791 // No luck, do a generic load. 6834 // No luck, do a generic load.
6792 return BuildLoadNamedGeneric(object, name, expr); 6835 return BuildLoadNamedGeneric(object, name, expr);
6793 } 6836 }
6794 6837
6795 6838
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
7230 ASSERT(!HasStackOverflow()); 7273 ASSERT(!HasStackOverflow());
7231 ASSERT(current_block() != NULL); 7274 ASSERT(current_block() != NULL);
7232 ASSERT(current_block()->HasPredecessor()); 7275 ASSERT(current_block()->HasPredecessor());
7233 expr->RecordTypeFeedback(oracle(), zone()); 7276 expr->RecordTypeFeedback(oracle(), zone());
7234 7277
7235 if (TryArgumentsAccess(expr)) return; 7278 if (TryArgumentsAccess(expr)) return;
7236 7279
7237 CHECK_ALIVE(VisitForValue(expr->obj())); 7280 CHECK_ALIVE(VisitForValue(expr->obj()));
7238 7281
7239 HInstruction* instr = NULL; 7282 HInstruction* instr = NULL;
7240 if (expr->AsProperty()->IsArrayLength()) { 7283 if (expr->IsStringLength()) {
7241 HValue* array = Pop();
7242 AddInstruction(new(zone()) HCheckNonSmi(array));
7243 HInstruction* mapcheck =
7244 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone()));
7245 instr = new(zone()) HJSArrayLength(array, mapcheck);
7246 } else if (expr->IsStringLength()) {
7247 HValue* string = Pop(); 7284 HValue* string = Pop();
7248 AddInstruction(new(zone()) HCheckNonSmi(string)); 7285 AddInstruction(new(zone()) HCheckNonSmi(string));
7249 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7286 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7250 instr = HStringLength::New(zone(), string); 7287 instr = HStringLength::New(zone(), string);
7251 } else if (expr->IsStringAccess()) { 7288 } else if (expr->IsStringAccess()) {
7252 CHECK_ALIVE(VisitForValue(expr->key())); 7289 CHECK_ALIVE(VisitForValue(expr->key()));
7253 HValue* index = Pop(); 7290 HValue* index = Pop();
7254 HValue* string = Pop(); 7291 HValue* string = Pop();
7255 HValue* context = environment()->LookupContext(); 7292 HValue* context = environment()->LookupContext();
7256 HInstruction* char_code = 7293 HInstruction* char_code =
(...skipping 3692 matching lines...) Expand 10 before | Expand all | Expand 10 after
10949 } 10986 }
10950 } 10987 }
10951 10988
10952 #ifdef DEBUG 10989 #ifdef DEBUG
10953 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10990 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10954 if (allocator_ != NULL) allocator_->Verify(); 10991 if (allocator_ != NULL) allocator_->Verify();
10955 #endif 10992 #endif
10956 } 10993 }
10957 10994
10958 } } // namespace v8::internal 10995 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | src/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698