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

Side by Side Diff: src/objects.cc

Issue 6902029: Add prototype transitions cache to Map. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 7 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 6865 matching lines...) Expand 10 before | Expand all | Expand 10 after
6876 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); 6876 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1);
6877 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6877 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6878 } 6878 }
6879 FixedArray::cast(obj)->set(0, len); 6879 FixedArray::cast(obj)->set(0, len);
6880 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 6880 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
6881 set_elements(FixedArray::cast(obj)); 6881 set_elements(FixedArray::cast(obj));
6882 return this; 6882 return this;
6883 } 6883 }
6884 6884
6885 6885
6886 Object* Map::GetPrototypeTransition(Object* prototype) {
6887 FixedArray* cache = prototype_transitions();
6888 int capacity = cache->length();
6889 if (capacity == 0) return NULL;
6890 int finger = Smi::cast(cache->get(0))->value();
6891 for (int i = 1; i < finger; i += 2) {
6892 if (cache->get(i) == prototype) return cache->get(i + 1);
6893 }
6894 return NULL;
6895 }
6896
6897
6898 MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
6899 // Don't cache prototype transition if this map is shared.
6900 if (is_shared() || !FLAG_cache_prototype_transitions) return this;
6901
6902 FixedArray* cache = prototype_transitions();
6903
6904 int capacity = cache->length();
6905 int finger = (capacity == 0) ? 1 : Smi::cast(cache->get(0))->value();
6906
6907 if (finger >= capacity) {
Mads Ager (chromium) 2011/04/26 09:14:23 I think we want to put a limit on the number of pr
6908 FixedArray* new_cache;
6909 { MaybeObject* maybe_cache = heap()->AllocateFixedArray(finger * 2 + 1);
6910 if (!maybe_cache->To<FixedArray>(&new_cache)) return maybe_cache;
6911 }
6912
6913 for (int i = 1; i < capacity; i++) new_cache->set(i, cache->get(i));
6914 cache = new_cache;
6915 set_prototype_transitions(cache);
6916 }
6917
6918 cache->set(finger, prototype);
6919 cache->set(finger + 1, map);
6920 cache->set(0, Smi::FromInt(finger + 2));
6921
6922 return cache;
6923 }
6924
6925
6886 MaybeObject* JSObject::SetPrototype(Object* value, 6926 MaybeObject* JSObject::SetPrototype(Object* value,
6887 bool skip_hidden_prototypes) { 6927 bool skip_hidden_prototypes) {
6888 Heap* heap = GetHeap(); 6928 Heap* heap = GetHeap();
6889 // Silently ignore the change if value is not a JSObject or null. 6929 // Silently ignore the change if value is not a JSObject or null.
6890 // SpiderMonkey behaves this way. 6930 // SpiderMonkey behaves this way.
6891 if (!value->IsJSObject() && !value->IsNull()) return value; 6931 if (!value->IsJSObject() && !value->IsNull()) return value;
6892 6932
6893 // From 8.6.2 Object Internal Methods 6933 // From 8.6.2 Object Internal Methods
6894 // ... 6934 // ...
6895 // In addition, if [[Extensible]] is false the value of the [[Class]] and 6935 // In addition, if [[Extensible]] is false the value of the [[Class]] and
(...skipping 30 matching lines...) Expand all
6926 // hidden and set the new prototype on that object. 6966 // hidden and set the new prototype on that object.
6927 Object* current_proto = real_receiver->GetPrototype(); 6967 Object* current_proto = real_receiver->GetPrototype();
6928 while (current_proto->IsJSObject() && 6968 while (current_proto->IsJSObject() &&
6929 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { 6969 JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
6930 real_receiver = JSObject::cast(current_proto); 6970 real_receiver = JSObject::cast(current_proto);
6931 current_proto = current_proto->GetPrototype(); 6971 current_proto = current_proto->GetPrototype();
6932 } 6972 }
6933 } 6973 }
6934 6974
6935 // Set the new prototype of the object. 6975 // Set the new prototype of the object.
6936 Object* new_map; 6976 Map* map = real_receiver->map();
6937 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions(); 6977
6938 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 6978 // Nothing to do if prototype is already set.
6979 if (map->prototype() == value) return value;
6980
6981 Object* new_map = map->GetPrototypeTransition(value);
6982 if (new_map == NULL) {
6983 { MaybeObject* maybe_new_map = map->CopyDropTransitions();
6984 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
6985 }
6986
6987 { MaybeObject* maybe_new_cache =
6988 map->PutPrototypeTransition(value, Map::cast(new_map));
6989 if (maybe_new_cache->IsFailure()) return maybe_new_cache;
6990 }
6991
6992 Map::cast(new_map)->set_prototype(value);
6939 } 6993 }
6940 Map::cast(new_map)->set_prototype(value); 6994 ASSERT(Map::cast(new_map)->prototype() == value);
6941 real_receiver->set_map(Map::cast(new_map)); 6995 real_receiver->set_map(Map::cast(new_map));
6942 6996
6943 heap->ClearInstanceofCache(); 6997 heap->ClearInstanceofCache();
6944 6998
6945 return value; 6999 return value;
6946 } 7000 }
6947 7001
6948 7002
6949 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { 7003 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
6950 switch (GetElementsKind()) { 7004 switch (GetElementsKind()) {
(...skipping 3415 matching lines...) Expand 10 before | Expand all | Expand 10 after
10366 if (break_point_objects()->IsUndefined()) return 0; 10420 if (break_point_objects()->IsUndefined()) return 0;
10367 // Single beak point. 10421 // Single beak point.
10368 if (!break_point_objects()->IsFixedArray()) return 1; 10422 if (!break_point_objects()->IsFixedArray()) return 1;
10369 // Multiple break points. 10423 // Multiple break points.
10370 return FixedArray::cast(break_point_objects())->length(); 10424 return FixedArray::cast(break_point_objects())->length();
10371 } 10425 }
10372 #endif 10426 #endif
10373 10427
10374 10428
10375 } } // namespace v8::internal 10429 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698