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

Side by Side Diff: src/hydrogen.cc

Issue 21107004: Remove special handling of fields in combination with elements transitions in Crankshaft. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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
« no previous file with comments | « no previous file | 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 4529 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 (type->unused_property_fields() > 0); 4540 (type->unused_property_fields() > 0);
4541 } 4541 }
4542 4542
4543 4543
4544 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 4544 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
4545 BuildCheckHeapObject(object); 4545 BuildCheckHeapObject(object);
4546 AddInstruction(HCheckMaps::New(object, map, zone(), top_info())); 4546 AddInstruction(HCheckMaps::New(object, map, zone(), top_info()));
4547 } 4547 }
4548 4548
4549 4549
4550 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
4551 Handle<Map> map) {
4552 BuildCheckHeapObject(object);
4553 AddInstruction(HCheckMaps::NewWithTransitions(
4554 object, map, zone(), top_info()));
4555 }
4556
4557
4558 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 4550 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
4559 HValue* object, 4551 HValue* object,
4560 Handle<String> name, 4552 Handle<String> name,
4561 HValue* value, 4553 HValue* value,
4562 Handle<Map> map, 4554 Handle<Map> map,
4563 LookupResult* lookup) { 4555 LookupResult* lookup) {
4564 ASSERT(lookup->IsFound()); 4556 ASSERT(lookup->IsFound());
4565 // If the property does not exist yet, we have to check that it wasn't made 4557 // If the property does not exist yet, we have to check that it wasn't made
4566 // readonly or turned into a setter by some meanwhile modifications on the 4558 // readonly or turned into a setter by some meanwhile modifications on the
4567 // prototype chain. 4559 // prototype chain.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4647 4639
4648 4640
4649 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( 4641 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
4650 HValue* object, 4642 HValue* object,
4651 Handle<String> name, 4643 Handle<String> name,
4652 HValue* value, 4644 HValue* value,
4653 Handle<Map> map) { 4645 Handle<Map> map) {
4654 // Handle a store to a known field. 4646 // Handle a store to a known field.
4655 LookupResult lookup(isolate()); 4647 LookupResult lookup(isolate());
4656 if (ComputeLoadStoreField(map, name, &lookup, true)) { 4648 if (ComputeLoadStoreField(map, name, &lookup, true)) {
4657 AddCheckMapsWithTransitions(object, map); 4649 AddCheckMap(object, map);
4658 return BuildStoreNamedField(object, name, value, map, &lookup); 4650 return BuildStoreNamedField(object, name, value, map, &lookup);
4659 } 4651 }
4660 4652
4661 // No luck, do a generic store. 4653 // No luck, do a generic store.
4662 return BuildStoreNamedGeneric(object, name, value); 4654 return BuildStoreNamedGeneric(object, name, value);
4663 } 4655 }
4664 4656
4665 4657
4666 static bool CanLoadPropertyFromPrototype(Handle<Map> map, 4658 static bool CanLoadPropertyFromPrototype(Handle<Map> map,
4667 Handle<Name> name, 4659 Handle<Name> name,
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after
5427 HValue* object, 5419 HValue* object,
5428 Handle<String> name, 5420 Handle<String> name,
5429 Property* expr, 5421 Property* expr,
5430 Handle<Map> map) { 5422 Handle<Map> map) {
5431 // Handle a load from a known field. 5423 // Handle a load from a known field.
5432 ASSERT(!map->is_dictionary_map()); 5424 ASSERT(!map->is_dictionary_map());
5433 5425
5434 // Handle access to various length properties 5426 // Handle access to various length properties
5435 if (name->Equals(isolate()->heap()->length_string())) { 5427 if (name->Equals(isolate()->heap()->length_string())) {
5436 if (map->instance_type() == JS_ARRAY_TYPE) { 5428 if (map->instance_type() == JS_ARRAY_TYPE) {
5437 AddCheckMapsWithTransitions(object, map); 5429 AddCheckMap(object, map);
5438 return new(zone()) HLoadNamedField(object, 5430 return new(zone()) HLoadNamedField(object,
5439 HObjectAccess::ForArrayLength(map->elements_kind())); 5431 HObjectAccess::ForArrayLength(map->elements_kind()));
5440 } 5432 }
5441 } 5433 }
5442 5434
5443 LookupResult lookup(isolate()); 5435 LookupResult lookup(isolate());
5444 map->LookupDescriptor(NULL, *name, &lookup); 5436 map->LookupDescriptor(NULL, *name, &lookup);
5445 if (lookup.IsField()) { 5437 if (lookup.IsField()) {
5446 AddCheckMap(object, map); 5438 AddCheckMap(object, map);
5447 return BuildLoadNamedField(object, 5439 return BuildLoadNamedField(object,
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
5969 } 5961 }
5970 5962
5971 5963
5972 void HOptimizedGraphBuilder::AddCheckConstantFunction( 5964 void HOptimizedGraphBuilder::AddCheckConstantFunction(
5973 Handle<JSObject> holder, 5965 Handle<JSObject> holder,
5974 HValue* receiver, 5966 HValue* receiver,
5975 Handle<Map> receiver_map) { 5967 Handle<Map> receiver_map) {
5976 // Constant functions have the nice property that the map will change if they 5968 // Constant functions have the nice property that the map will change if they
5977 // are overwritten. Therefore it is enough to check the map of the holder and 5969 // are overwritten. Therefore it is enough to check the map of the holder and
5978 // its prototypes. 5970 // its prototypes.
5979 AddCheckMapsWithTransitions(receiver, receiver_map); 5971 AddCheckMap(receiver, receiver_map);
5980 AddCheckPrototypeMaps(holder, receiver_map); 5972 AddCheckPrototypeMaps(holder, receiver_map);
5981 } 5973 }
5982 5974
5983 5975
5984 class FunctionSorter { 5976 class FunctionSorter {
5985 public: 5977 public:
5986 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } 5978 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
5987 FunctionSorter(int index, int ticks, int ast_length, int src_length) 5979 FunctionSorter(int index, int ticks, int ast_length, int src_length)
5988 : index_(index), 5980 : index_(index),
5989 ticks_(ticks), 5981 ticks_(ticks),
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
6922 known_function, 6914 known_function,
6923 arguments_count); 6915 arguments_count);
6924 Drop(arguments_count); 6916 Drop(arguments_count);
6925 call->set_position(expr->position()); 6917 call->set_position(expr->position());
6926 ast_context()->ReturnInstruction(call, expr->id()); 6918 ast_context()->ReturnInstruction(call, expr->id());
6927 return true; 6919 return true;
6928 } 6920 }
6929 } 6921 }
6930 6922
6931 6923
6932 // Checks if all maps in |types| are from the same family, i.e., are elements
6933 // transitions of each other. Returns either NULL if they are not from the same
6934 // family, or a Map* indicating the map with the first elements kind of the
6935 // family that is in the list.
6936 static Map* CheckSameElementsFamily(SmallMapList* types) {
6937 if (types->length() <= 1) return NULL;
6938 // Check if all maps belong to the same transition family.
6939 Map* kinds[kFastElementsKindCount];
6940 Map* first_map = *types->first();
6941 ElementsKind first_kind = first_map->elements_kind();
6942 if (!IsFastElementsKind(first_kind)) return NULL;
6943 int first_index = GetSequenceIndexFromFastElementsKind(first_kind);
6944 int last_index = first_index;
6945
6946 for (int i = 0; i < kFastElementsKindCount; i++) kinds[i] = NULL;
6947
6948 kinds[first_index] = first_map;
6949
6950 for (int i = 1; i < types->length(); ++i) {
6951 Map* map = *types->at(i);
6952 ElementsKind elements_kind = map->elements_kind();
6953 if (!IsFastElementsKind(elements_kind)) return NULL;
6954 int index = GetSequenceIndexFromFastElementsKind(elements_kind);
6955 if (index < first_index) {
6956 first_index = index;
6957 } else if (index > last_index) {
6958 last_index = index;
6959 } else if (kinds[index] != map) {
6960 return NULL;
6961 }
6962 kinds[index] = map;
6963 }
6964
6965 Map* current = kinds[first_index];
6966 for (int i = first_index + 1; i <= last_index; i++) {
6967 Map* next = kinds[i];
6968 if (next != NULL) {
6969 ElementsKind current_kind = next->elements_kind();
6970 if (next != current->LookupElementsTransitionMap(current_kind)) {
6971 return NULL;
6972 }
6973 current = next;
6974 }
6975 }
6976
6977 return kinds[first_index];
6978 }
6979
6980
6981 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 6924 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
6982 ASSERT(!HasStackOverflow()); 6925 ASSERT(!HasStackOverflow());
6983 ASSERT(current_block() != NULL); 6926 ASSERT(current_block() != NULL);
6984 ASSERT(current_block()->HasPredecessor()); 6927 ASSERT(current_block()->HasPredecessor());
6985 Expression* callee = expr->expression(); 6928 Expression* callee = expr->expression();
6986 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 6929 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
6987 HInstruction* call = NULL; 6930 HInstruction* call = NULL;
6988 6931
6989 Property* prop = callee->AsProperty(); 6932 Property* prop = callee->AsProperty();
6990 if (prop != NULL) { 6933 if (prop != NULL) {
(...skipping 25 matching lines...) Expand all
7016 6959
7017 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 6960 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
7018 SmallMapList* types = expr->GetReceiverTypes(); 6961 SmallMapList* types = expr->GetReceiverTypes();
7019 6962
7020 bool monomorphic = expr->IsMonomorphic(); 6963 bool monomorphic = expr->IsMonomorphic();
7021 Handle<Map> receiver_map; 6964 Handle<Map> receiver_map;
7022 if (monomorphic) { 6965 if (monomorphic) {
7023 receiver_map = (types == NULL || types->is_empty()) 6966 receiver_map = (types == NULL || types->is_empty())
7024 ? Handle<Map>::null() 6967 ? Handle<Map>::null()
7025 : types->first(); 6968 : types->first();
7026 } else {
7027 Map* family_map = CheckSameElementsFamily(types);
7028 if (family_map != NULL) {
7029 receiver_map = Handle<Map>(family_map);
7030 monomorphic = expr->ComputeTarget(receiver_map, name);
7031 }
7032 } 6969 }
7033 6970
7034 HValue* receiver = 6971 HValue* receiver =
7035 environment()->ExpressionStackAt(expr->arguments()->length()); 6972 environment()->ExpressionStackAt(expr->arguments()->length());
7036 if (monomorphic) { 6973 if (monomorphic) {
7037 if (TryInlineBuiltinMethodCall(expr, 6974 if (TryInlineBuiltinMethodCall(expr,
7038 receiver, 6975 receiver,
7039 receiver_map, 6976 receiver_map,
7040 expr->check_type())) { 6977 expr->check_type())) {
7041 if (FLAG_trace_inlining) { 6978 if (FLAG_trace_inlining) {
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
8213 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 8150 combined_type = left_type = right_type = handle(Type::Any(), isolate());
8214 } 8151 }
8215 8152
8216 if (combined_type->Is(Type::Receiver())) { 8153 if (combined_type->Is(Type::Receiver())) {
8217 switch (op) { 8154 switch (op) {
8218 case Token::EQ: 8155 case Token::EQ:
8219 case Token::EQ_STRICT: { 8156 case Token::EQ_STRICT: {
8220 // Can we get away with map check and not instance type check? 8157 // Can we get away with map check and not instance type check?
8221 if (combined_type->IsClass()) { 8158 if (combined_type->IsClass()) {
8222 Handle<Map> map = combined_type->AsClass(); 8159 Handle<Map> map = combined_type->AsClass();
8223 AddCheckMapsWithTransitions(left, map); 8160 AddCheckMap(left, map);
8224 AddCheckMapsWithTransitions(right, map); 8161 AddCheckMap(right, map);
8225 HCompareObjectEqAndBranch* result = 8162 HCompareObjectEqAndBranch* result =
8226 new(zone()) HCompareObjectEqAndBranch(left, right); 8163 new(zone()) HCompareObjectEqAndBranch(left, right);
8227 result->set_position(expr->position()); 8164 result->set_position(expr->position());
8228 return ast_context()->ReturnControl(result, expr->id()); 8165 return ast_context()->ReturnControl(result, expr->id());
8229 } else { 8166 } else {
8230 BuildCheckHeapObject(left); 8167 BuildCheckHeapObject(left);
8231 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 8168 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
8232 BuildCheckHeapObject(right); 8169 BuildCheckHeapObject(right);
8233 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 8170 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
8234 HCompareObjectEqAndBranch* result = 8171 HCompareObjectEqAndBranch* result =
(...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after
9941 if (ShouldProduceTraceOutput()) { 9878 if (ShouldProduceTraceOutput()) {
9942 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9879 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9943 } 9880 }
9944 9881
9945 #ifdef DEBUG 9882 #ifdef DEBUG
9946 graph_->Verify(false); // No full verify. 9883 graph_->Verify(false); // No full verify.
9947 #endif 9884 #endif
9948 } 9885 }
9949 9886
9950 } } // namespace v8::internal 9887 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698