Revision: 22826
Author: [email protected]
Date: Mon Aug 4 15:02:07 2014 UTC
Log: Keep function.prototype fast.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/437083004
http://code.google.com/p/v8/source/detail?r=22826
Modified:
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/test/mjsunit/fast-prototype.js
=======================================
--- /branches/bleeding_edge/src/factory.cc Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc Mon Aug 4 15:02:07 2014 UTC
@@ -1318,7 +1318,7 @@
// maps between prototypes of different constructors.
Handle<JSFunction> object_function(native_context->object_function());
DCHECK(object_function->has_initial_map());
- new_map = Map::Copy(handle(object_function->initial_map()));
+ new_map =
Map::CopyAsPrototypeMap(handle(object_function->initial_map()));
}
Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Aug 4 15:02:07 2014 UTC
@@ -2115,6 +2115,7 @@
bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
if (unused_property_fields() != 0) return false;
+ if (is_prototype_map()) return false;
int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
int limit = Max(minimum, inobject_properties());
int external = NumberOfFields() - inobject_properties();
@@ -4443,6 +4444,15 @@
bool Map::is_extensible() {
return ((1 << kIsExtensible) & bit_field2()) != 0;
}
+
+
+void Map::mark_prototype_map() {
+ set_bit_field2(IsPrototypeMapBits::update(bit_field2(), true));
+}
+
+bool Map::is_prototype_map() {
+ return IsPrototypeMapBits::decode(bit_field2());
+}
void Map::set_is_shared(bool value) {
=======================================
--- /branches/bleeding_edge/src/objects.cc Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Aug 4 15:02:07 2014 UTC
@@ -7264,6 +7264,13 @@
new_map->SetBackPointer(*map);
return new_map;
}
+
+
+Handle<Map> Map::CopyAsPrototypeMap(Handle<Map> map) {
+ Handle<Map> result = Copy(map);
+ result->mark_prototype_map();
+ return result;
+}
Handle<Map> Map::Copy(Handle<Map> map) {
@@ -10003,7 +10010,12 @@
// First some logic for the map of the prototype to make sure it is in
fast
// mode.
if (value->IsJSObject()) {
- JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+ Handle<JSObject> js_proto = Handle<JSObject>::cast(value);
+ JSObject::OptimizeAsPrototype(js_proto);
+ if (js_proto->HasFastProperties()) {
+ Handle<Map> new_map =
Map::CopyAsPrototypeMap(handle(js_proto->map()));
+ JSObject::MigrateToMap(js_proto, new_map);
+ }
}
// Now some logic for the maps of the objects that are created by using
this
@@ -10120,15 +10132,9 @@
Handle<Object> prototype;
if (function->has_instance_prototype()) {
prototype = handle(function->instance_prototype(), isolate);
- for (PrototypeIterator iter(isolate, prototype,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(); iter.Advance()) {
- if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
- break;
- }
- JSObject::OptimizeAsPrototype(
- Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
- }
+ // TODO(verwaest): Remove once "delete" keeps objects marked as
prototypes
+ // fast as well.
+ JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(prototype));
} else {
prototype = isolate->factory()->NewFunctionPrototype(function);
}
=======================================
--- /branches/bleeding_edge/src/objects.h Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Aug 4 15:02:07 2014 UTC
@@ -6204,6 +6204,8 @@
inline void set_is_extensible(bool value);
inline bool is_extensible();
+ inline void mark_prototype_map();
+ inline bool is_prototype_map();
inline void set_elements_kind(ElementsKind elements_kind) {
DCHECK(elements_kind < kElementsKindCount);
@@ -6537,6 +6539,7 @@
// Returns a copy of the map, with all transitions dropped from the
// instance descriptors.
static Handle<Map> Copy(Handle<Map> map);
+ static Handle<Map> CopyAsPrototypeMap(Handle<Map> map);
static Handle<Map> Create(Handle<JSFunction> constructor,
int extra_inobject_properties);
@@ -6736,7 +6739,7 @@
// Bit positions for bit field 2
static const int kIsExtensible = 0;
static const int kStringWrapperSafeForDefaultValueOf = 1;
- // Currently bit 2 is not used.
+ class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
// Derived values from bit field 2
=======================================
--- /branches/bleeding_edge/test/mjsunit/fast-prototype.js Tue Jan 21
12:41:25 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/fast-prototype.js Mon Aug 4
15:02:07 2014 UTC
@@ -72,10 +72,15 @@
// Still fast
assertTrue(%HasFastProperties(proto));
AddProps(proto);
- // After we add all those properties it went slow mode again :-(
- assertFalse(%HasFastProperties(proto));
+ if (set__proto__) {
+ // After we add all those properties it went slow mode again :-(
+ assertFalse(%HasFastProperties(proto));
+ } else {
+ // .prototype keeps it fast.
+ assertTrue(%HasFastProperties(proto));
+ }
}
- if (same_map_as && !add_first) {
+ if (same_map_as && !add_first && set__proto__) {
assertTrue(%HaveSameMap(same_map_as, proto));
}
return proto;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.