Revision: 23042
Author: [email protected]
Date: Mon Aug 11 14:00:58 2014 UTC
Log: Tag all prototypes as proto, except those set using __proto__
BUG=
[email protected], [email protected]
Review URL: https://codereview.chromium.org/450303003
http://code.google.com/p/v8/source/detail?r=23042
Added:
/branches/bleeding_edge/test/mjsunit/runtime-gen/internalsetprototype.js
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/apinatives.js
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/generator.js
/branches/bleeding_edge/src/math.js
/branches/bleeding_edge/src/objects-debug.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/v8natives.js
/branches/bleeding_edge/tools/generate-runtime-tests.py
=======================================
--- /dev/null
+++
/branches/bleeding_edge/test/mjsunit/runtime-gen/internalsetprototype.js
Mon Aug 11 14:00:58 2014 UTC
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _obj = new Object();
+var _prototype = new Object();
+%InternalSetPrototype(_obj, _prototype);
=======================================
--- /branches/bleeding_edge/src/api.cc Thu Aug 7 08:55:49 2014 UTC
+++ /branches/bleeding_edge/src/api.cc Mon Aug 11 14:00:58 2014 UTC
@@ -3204,8 +3204,8 @@
// to propagate outside.
TryCatch try_catch;
EXCEPTION_PREAMBLE(isolate);
- i::MaybeHandle<i::Object> result = i::JSObject::SetPrototype(
- self, value_obj);
+ i::MaybeHandle<i::Object> result =
+ i::JSObject::SetPrototype(self, value_obj, false);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
=======================================
--- /branches/bleeding_edge/src/apinatives.js Tue Jul 29 08:09:14 2014 UTC
+++ /branches/bleeding_edge/src/apinatives.js Mon Aug 11 14:00:58 2014 UTC
@@ -68,7 +68,7 @@
// internal ToBoolean doesn't handle that!
if (typeof parent !== 'undefined') {
var parent_fun = Instantiate(parent);
- %SetPrototype(prototype, parent_fun.prototype);
+ %InternalSetPrototype(prototype, parent_fun.prototype);
}
}
var fun = %CreateApiFunction(data, prototype);
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Fri Aug 8 11:42:59 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Mon Aug 11 14:00:58 2014 UTC
@@ -480,7 +480,8 @@
Handle<JSFunction> object_fun = factory->NewFunction(object_name);
Handle<Map> object_function_map =
factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- JSFunction::SetInitialMap(object_fun, object_function_map);
+ JSFunction::SetInitialMap(object_fun, object_function_map,
+ isolate->factory()->null_value());
object_function_map->set_unused_property_fields(
JSObject::kInitialGlobalObjectUnusedPropertiesCount);
@@ -490,6 +491,9 @@
Handle<JSObject> prototype = factory->NewJSObject(
isolate->object_function(),
TENURED);
+ Handle<Map> map = Map::Copy(handle(prototype->map()));
+ map->set_is_prototype_map(true);
+ prototype->set_map(*map);
native_context()->set_initial_object_prototype(*prototype);
// For bootstrapping set the array prototype to be the same as the
object
@@ -507,6 +511,15 @@
Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype(
empty_string, code);
+ // Allocate the function map first and then patch the prototype later
+ Handle<Map> empty_function_map =
+ CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
+ DCHECK(!empty_function_map->is_dictionary_map());
+ empty_function_map->set_prototype(
+ native_context()->object_function()->prototype());
+ empty_function_map->set_is_prototype_map(true);
+ empty_function->set_map(*empty_function_map);
+
// --- E m p t y ---
Handle<String> source = factory->NewStringFromStaticAscii("() {}");
Handle<Script> script = factory->NewScript(source);
@@ -521,13 +534,6 @@
native_context()->sloppy_function_without_prototype_map()->
set_prototype(*empty_function);
sloppy_function_map_writable_prototype_->set_prototype(*empty_function);
-
- // Allocate the function map first and then patch the prototype later
- Handle<Map> empty_function_map =
- CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
- empty_function_map->set_prototype(
- native_context()->object_function()->prototype());
- empty_function->set_map(*empty_function_map);
return empty_function;
}
@@ -1082,6 +1088,7 @@
proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0),
SKIP_WRITE_BARRIER); // It's a Smi.
+ proto_map->set_is_prototype_map(true);
initial_map->set_prototype(*proto);
factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
JSRegExp::IRREGEXP,
factory->empty_string(),
@@ -1204,13 +1211,13 @@
}
map->set_function_with_prototype(true);
- map->set_prototype(native_context()->object_function()->prototype());
map->set_pre_allocated_property_fields(2);
map->set_inobject_properties(2);
native_context()->set_sloppy_arguments_map(*map);
DCHECK(!function->has_initial_map());
- JSFunction::SetInitialMap(function, map);
+ JSFunction::SetInitialMap(function, map,
+ isolate->initial_object_prototype());
DCHECK(map->inobject_properties() > Heap::kArgumentsCalleeIndex);
DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex);
@@ -1334,7 +1341,8 @@
JS_TYPED_ARRAY_TYPE,
JSTypedArray::kSizeWithInternalFields,
elements_kind);
- JSFunction::SetInitialMap(result, initial_map);
+ JSFunction::SetInitialMap(result, initial_map,
+ handle(initial_map->prototype(), isolate()));
*fun = result;
ElementsKind external_kind =
GetNextTransitionElementsKind(elements_kind);
@@ -1652,7 +1660,7 @@
Handle<Map> original_map(array_function->initial_map());
Handle<Map> initial_map = Map::Copy(original_map);
initial_map->set_elements_kind(elements_kind);
- JSFunction::SetInitialMap(array_function, initial_map);
+ JSFunction::SetInitialMap(array_function, initial_map, prototype);
// Make "length" magic on instances.
Map::EnsureDescriptorSlack(initial_map, 1);
=======================================
--- /branches/bleeding_edge/src/factory.cc Thu Aug 7 16:14:22 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc Mon Aug 11 14:00:58 2014 UTC
@@ -1289,8 +1289,8 @@
prototype = NewFunctionPrototype(function);
}
- initial_map->set_prototype(*prototype);
- JSFunction::SetInitialMap(function, initial_map);
+ JSFunction::SetInitialMap(function, initial_map,
+ Handle<JSReceiver>::cast(prototype));
return function;
}
@@ -1321,6 +1321,7 @@
new_map = handle(object_function->initial_map());
}
+ DCHECK(!new_map->is_prototype_map());
Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
if (!function->shared()->is_generator()) {
=======================================
--- /branches/bleeding_edge/src/generator.js Mon Jul 14 14:05:30 2014 UTC
+++ /branches/bleeding_edge/src/generator.js Mon Aug 11 14:00:58 2014 UTC
@@ -67,11 +67,11 @@
GeneratorObjectIterator, DONT_ENUM | DONT_DELETE | READ_ONLY);
%AddNamedProperty(GeneratorObjectPrototype, "constructor",
GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE | READ_ONLY);
- %SetPrototype(GeneratorFunctionPrototype, $Function.prototype);
+ %InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype);
%SetCode(GeneratorFunctionPrototype,
GeneratorFunctionPrototypeConstructor);
%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
GeneratorFunction, DONT_ENUM | DONT_DELETE | READ_ONLY);
- %SetPrototype(GeneratorFunction, $Function);
+ %InternalSetPrototype(GeneratorFunction, $Function);
%SetCode(GeneratorFunction, GeneratorFunctionConstructor);
}
=======================================
--- /branches/bleeding_edge/src/math.js Wed Aug 6 11:39:39 2014 UTC
+++ /branches/bleeding_edge/src/math.js Mon Aug 11 14:00:58 2014 UTC
@@ -372,7 +372,7 @@
function SetUpMath() {
%CheckIsBootstrapping();
- %SetPrototype($Math, $Object.prototype);
+ %InternalSetPrototype($Math, $Object.prototype);
%AddNamedProperty(global, "Math", $Math, DONT_ENUM);
%FunctionSetInstanceClassName(MathConstructor, 'Math');
=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Thu Aug 7 12:21:01 2014
UTC
+++ /branches/bleeding_edge/src/objects-debug.cc Mon Aug 11 14:00:58 2014
UTC
@@ -308,9 +308,9 @@
}
-void Map::SharedMapVerify() {
+void Map::DictionaryMapVerify() {
MapVerify();
- CHECK(is_shared());
+ CHECK(is_dictionary_map());
CHECK(instance_descriptors()->IsEmpty());
CHECK_EQ(0, pre_allocated_property_fields());
CHECK_EQ(0, unused_property_fields());
@@ -1012,7 +1012,7 @@
for (int i = 0; i < length(); i++) {
Object* e = FixedArray::get(i);
if (e->IsMap()) {
- Map::cast(e)->SharedMapVerify();
+ Map::cast(e)->DictionaryMapVerify();
} else {
CHECK(e->IsUndefined());
}
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Thu Aug 7 16:14:22 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Aug 11 14:00:58 2014 UTC
@@ -2206,7 +2206,8 @@
void FixedArray::set(int index, Object* value) {
- DCHECK(map() != GetHeap()->fixed_cow_array_map());
+ DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
+ DCHECK_EQ(FIXED_ARRAY_TYPE, map()->instance_type());
DCHECK(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kPointerSize;
WRITE_FIELD(this, offset, value);
@@ -4460,15 +4461,6 @@
}
-void Map::set_is_shared(bool value) {
- set_bit_field3(IsShared::update(bit_field3(), value));
-}
-
-
-bool Map::is_shared() {
- return IsShared::decode(bit_field3()); }
-
-
void Map::set_dictionary_map(bool value) {
uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value);
new_bit_field3 = IsUnstable::update(new_bit_field3, value);
@@ -4486,8 +4478,8 @@
}
-void Map::set_owns_descriptors(bool is_shared) {
- set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
+void Map::set_owns_descriptors(bool owns_descriptors) {
+ set_bit_field3(OwnsDescriptors::update(bit_field3(), owns_descriptors));
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Mon Aug 11 12:26:17 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Aug 11 14:00:58 2014 UTC
@@ -3470,7 +3470,7 @@
bool allow_store_transition =
// Only remember the map transition if there is not an already
existing
// non-matching element transition.
- !map->IsUndefined() && !map->is_shared() &&
+ !map->IsUndefined() && !map->is_dictionary_map() &&
IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality.
@@ -4440,6 +4440,8 @@
MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
PropertyNormalizationMode mode) {
+ // Only use the cache once it is initialized.
+ if (!IsNormalizedMapCache(this)) return MaybeHandle<Map>();
DisallowHeapAllocation no_gc;
Object* value = FixedArray::get(GetIndex(fast_map));
if (!value->IsMap() ||
@@ -4452,6 +4454,8 @@
void NormalizedMapCache::Set(Handle<Map> fast_map,
Handle<Map> normalized_map) {
+ // Only use the cache once it is initialized.
+ if (!IsNormalizedMapCache(this)) return;
DisallowHeapAllocation no_gc;
DCHECK(normalized_map->is_dictionary_map());
FixedArray::set(GetIndex(fast_map), *normalized_map);
@@ -6981,17 +6985,14 @@
Handle<Map> new_map;
if (cache->Get(fast_map, mode).ToHandle(&new_map)) {
#ifdef VERIFY_HEAP
- if (FLAG_verify_heap) {
- new_map->SharedMapVerify();
- }
+ if (FLAG_verify_heap) new_map->DictionaryMapVerify();
#endif
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
// The cached map should match newly created normalized map
bit-by-bit,
// except for the code cache, which can contain some ics which can be
// applied to the shared map.
- Handle<Map> fresh = Map::CopyNormalized(
- fast_map, mode, SHARED_NORMALIZED_MAP);
+ Handle<Map> fresh = Map::CopyNormalized(fast_map, mode);
DCHECK(memcmp(fresh->address(),
new_map->address(),
@@ -7005,7 +7006,7 @@
}
#endif
} else {
- new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
+ new_map = Map::CopyNormalized(fast_map, mode);
cache->Set(fast_map, new_map);
isolate->counters()->normalized_maps()->Increment();
}
@@ -7015,8 +7016,7 @@
Handle<Map> Map::CopyNormalized(Handle<Map> map,
- PropertyNormalizationMode mode,
- NormalizedMapSharingMode sharing) {
+ PropertyNormalizationMode mode) {
int new_instance_size = map->instance_size();
if (mode == CLEAR_INOBJECT_PROPERTIES) {
new_instance_size -= map->inobject_properties() * kPointerSize;
@@ -7028,14 +7028,11 @@
result->set_inobject_properties(map->inobject_properties());
}
- result->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
result->set_dictionary_map(true);
result->set_migration_target(false);
#ifdef VERIFY_HEAP
- if (FLAG_verify_heap && result->is_shared()) {
- result->SharedMapVerify();
- }
+ if (FLAG_verify_heap) result->DictionaryMapVerify();
#endif
return result;
@@ -7051,7 +7048,6 @@
result->set_pre_allocated_property_fields(
map->pre_allocated_property_fields());
- result->set_is_shared(false);
result->ClearCodeCache(map->GetHeap());
map->NotifyLeafMapLayoutChange();
return result;
@@ -9812,20 +9808,29 @@
}
-void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
+void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
+ PrototypeOptimizationMode mode) {
if (object->IsGlobalObject()) return;
-
- // Make sure prototypes are fast objects and their maps have the bit set
- // so they remain fast.
+ if (object->IsJSGlobalProxy()) return;
+ if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) {
+ // First normalize to ensure all JSFunctions are CONSTANT.
+ JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0);
+ }
if (!object->HasFastProperties()) {
- MigrateSlowToFast(object, 0);
+ JSObject::MigrateSlowToFast(object, 0);
+ }
+ if (mode == FAST_PROTOTYPE && object->HasFastProperties() &&
+ !object->map()->is_prototype_map()) {
+ Handle<Map> new_map = Map::Copy(handle(object->map()));
+ JSObject::MigrateToMap(object, new_map);
+ object->map()->set_is_prototype_map(true);
}
}
void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
if (!object->map()->is_prototype_map()) return;
- OptimizeAsPrototype(object);
+ OptimizeAsPrototype(object, FAST_PROTOTYPE);
}
@@ -9876,20 +9881,29 @@
if (function->IsInobjectSlackTrackingInProgress()) {
function->CompleteInobjectSlackTracking();
}
+
Handle<Map> initial_map(function->initial_map(), isolate);
- Handle<Map> new_map = Map::Copy(initial_map);
- new_map->set_prototype(*value);
+
+ if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
+ initial_map->instance_type() == JS_OBJECT_TYPE) {
+ // Put the value in the initial map field until an initial map is
needed.
+ // At that point, a new initial map is created and the prototype is
put
+ // into the initial map where it belongs.
+ function->set_prototype_or_initial_map(*value);
+ } else {
+ Handle<Map> new_map = Map::Copy(initial_map);
+ JSFunction::SetInitialMap(function, new_map, value);
- // If the function is used as the global Array function, cache the
- // initial map (and transitioned versions) in the native context.
- Context* native_context = function->context()->native_context();
- Object* array_function =
native_context->get(Context::ARRAY_FUNCTION_INDEX);
- if (array_function->IsJSFunction() &&
- *function == JSFunction::cast(array_function)) {
- CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
+ // If the function is used as the global Array function, cache the
+ // initial map (and transitioned versions) in the native context.
+ Context* native_context = function->context()->native_context();
+ Object* array_function =
+ native_context->get(Context::ARRAY_FUNCTION_INDEX);
+ if (array_function->IsJSFunction() &&
+ *function == JSFunction::cast(array_function)) {
+ CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
+ }
}
-
- JSFunction::SetInitialMap(function, new_map);
// Deoptimize all code that embeds the previous initial map.
initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
@@ -9956,27 +9970,13 @@
}
-void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map>
map) {
- if (map->prototype()->IsJSObject()) {
- Handle<JSObject> js_proto = handle(JSObject::cast(map->prototype()));
- if (!js_proto->map()->is_prototype_map() &&
- !js_proto->map()->IsGlobalObjectMap() &&
- !js_proto->map()->IsJSGlobalProxyMap()) {
- // Normalize and turn fast again to make all functions CONSTANT
- // properties.
- if (!js_proto->GetIsolate()->bootstrapper()->IsActive()) {
- JSObject::NormalizeProperties(js_proto, KEEP_INOBJECT_PROPERTIES,
0);
- }
- if (!js_proto->HasFastProperties()) {
- JSObject::MigrateSlowToFast(js_proto, 0);
- }
- if (js_proto->HasFastProperties()) {
- Handle<Map> new_map = Map::Copy(handle(js_proto->map()));
- JSObject::MigrateToMap(js_proto, new_map);
- js_proto->map()->set_is_prototype_map(true);
- }
- }
+void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map>
map,
+ Handle<Object> prototype) {
+ if (prototype->IsJSObject()) {
+ Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype);
+ JSObject::OptimizeAsPrototype(js_proto, FAST_PROTOTYPE);
}
+ map->set_prototype(*prototype);
function->set_prototype_or_initial_map(*map);
map->set_constructor(*function);
}
@@ -10011,11 +10011,10 @@
}
map->set_inobject_properties(in_object_properties);
map->set_unused_property_fields(in_object_properties);
- map->set_prototype(*prototype);
DCHECK(map->has_fast_object_elements());
// Finally link initial map and constructor function.
- JSFunction::SetInitialMap(function, map);
+ JSFunction::SetInitialMap(function, map,
Handle<JSReceiver>::cast(prototype));
if (!function->shared()->is_generator()) {
function->StartInobjectSlackTracking();
@@ -11796,7 +11795,7 @@
// Don't cache prototype transition if this map is either shared, or a
map of
// a prototype.
if (map->is_prototype_map()) return map;
- if (map->is_shared() || !FLAG_cache_prototype_transitions) return map;
+ if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions)
return map;
const int step = kProtoTransitionElementsPerEntry;
const int header = kProtoTransitionHeaderSize;
@@ -12119,7 +12118,7 @@
MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Object> value,
- bool skip_hidden_prototypes) {
+ bool from_javascript) {
#ifdef DEBUG
int size = object->Size();
#endif
@@ -12164,7 +12163,7 @@
object->map()->DictionaryElementsInPrototypeChainOnly();
Handle<JSObject> real_receiver = object;
- if (skip_hidden_prototypes) {
+ if (from_javascript) {
// Find the first object in the chain whose prototype object is not
// hidden and set the new prototype on that object.
PrototypeIterator iter(isolate, real_receiver);
@@ -12182,7 +12181,9 @@
if (map->prototype() == *value) return value;
if (value->IsJSObject()) {
- JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+ PrototypeOptimizationMode mode =
+ from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
+ JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value), mode);
}
Handle<Map> new_map = Map::TransitionToPrototype(map, value);
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Aug 7 16:14:22 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Aug 11 14:00:58 2014 UTC
@@ -247,12 +247,12 @@
};
-// NormalizedMapSharingMode is used to specify whether a map may be shared
-// by different objects with normalized properties.
-enum NormalizedMapSharingMode {
- UNIQUE_NORMALIZED_MAP,
- SHARED_NORMALIZED_MAP
-};
+// Indicates how aggressively the prototype should be optimized.
FAST_PROTOTYPE
+// will give the fastest result by tailoring the map to the prototype, but
that
+// will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be
used
+// (at least for now) when dynamically modifying the prototype chain of an
+// object using __proto__ or Object.setPrototypeOf.
+enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
// Indicates whether transitions can be added to a source map or not.
@@ -2196,7 +2196,8 @@
Handle<Object> value,
PropertyDetails details);
- static void OptimizeAsPrototype(Handle<JSObject> object);
+ static void OptimizeAsPrototype(Handle<JSObject> object,
+ PrototypeOptimizationMode mode);
static void ReoptimizeIfPrototype(Handle<JSObject> object);
// Retrieve interceptors.
@@ -2475,9 +2476,7 @@
// Set the object's prototype (only JSReceiver and null are allowed
values).
MUST_USE_RESULT static MaybeHandle<Object> SetPrototype(
- Handle<JSObject> object,
- Handle<Object> value,
- bool skip_hidden_prototypes = false);
+ Handle<JSObject> object, Handle<Object> value, bool from_javascript);
// Initializes the body after properties slot, properties slot is
// initialized by set_properties. Fill the pre-allocated fields with
@@ -6125,15 +6124,16 @@
class NumberOfOwnDescriptorsBits: public BitField<int,
kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
- class IsShared: public BitField<bool, 20, 1> {};
- class DictionaryMap: public BitField<bool, 21, 1> {};
- class OwnsDescriptors: public BitField<bool, 22, 1> {};
- class HasInstanceCallHandler: public BitField<bool, 23, 1> {};
- class Deprecated: public BitField<bool, 24, 1> {};
- class IsFrozen: public BitField<bool, 25, 1> {};
- class IsUnstable: public BitField<bool, 26, 1> {};
- class IsMigrationTarget: public BitField<bool, 27, 1> {};
- class DoneInobjectSlackTracking: public BitField<bool, 28, 1> {};
+ class DictionaryMap : public BitField<bool, 20, 1> {};
+ class OwnsDescriptors : public BitField<bool, 21, 1> {};
+ class HasInstanceCallHandler : public BitField<bool, 22, 1> {};
+ class Deprecated : public BitField<bool, 23, 1> {};
+ class IsFrozen : public BitField<bool, 24, 1> {};
+ class IsUnstable : public BitField<bool, 25, 1> {};
+ class IsMigrationTarget : public BitField<bool, 26, 1> {};
+ class DoneInobjectSlackTracking : public BitField<bool, 27, 1> {};
+ // Bit 28 is free.
+
// Keep this bit field at the very end for better code in
// Builtins::kJSConstructStubGeneric stub.
class ConstructionCount: public BitField<int, 29, 3> {};
@@ -6335,12 +6335,6 @@
// function that was used to instantiate the object).
String* constructor_name();
- // Tells whether the map is shared between objects that may have
different
- // behavior. If true, the map should never be modified, instead a clone
- // should be created and modified.
- inline void set_is_shared(bool value);
- inline bool is_shared();
-
// Tells whether the map is used for JSObjects in dictionary mode (ie
// normalized objects, ie objects for which HasFastProperties returns
false).
// A map can never be used for both dictionary mode and fast mode
JSObjects.
@@ -6460,7 +6454,7 @@
}
inline bool owns_descriptors();
- inline void set_owns_descriptors(bool is_shared);
+ inline void set_owns_descriptors(bool owns_descriptors);
inline bool has_instance_call_handler();
inline void set_has_instance_call_handler();
inline void freeze();
@@ -6649,7 +6643,7 @@
DECLARE_VERIFIER(Map)
#ifdef VERIFY_HEAP
- void SharedMapVerify();
+ void DictionaryMapVerify();
void VerifyOmittedMapChecks();
#endif
@@ -6795,8 +6789,7 @@
TransitionFlag flag);
static Handle<Map> CopyNormalized(Handle<Map> map,
- PropertyNormalizationMode mode,
- NormalizedMapSharingMode sharing);
+ PropertyNormalizationMode mode);
// Fires when the layout of an object with a leaf map changes.
// This includes adding transitions to the leaf map or changing
@@ -7780,7 +7773,8 @@
// The initial map for an object created by this constructor.
inline Map* initial_map();
- static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map);
+ static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
+ Handle<Object> prototype);
inline bool has_initial_map();
static void EnsureHasInitialMap(Handle<JSFunction> function);
=======================================
--- /branches/bleeding_edge/src/runtime.cc Wed Aug 6 13:45:59 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Mon Aug 11 14:00:58 2014 UTC
@@ -1860,6 +1860,20 @@
}
return PrototypeIterator::GetCurrent(iter);
}
+
+
+RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ DCHECK(!obj->IsAccessCheckNeeded());
+ DCHECK(!obj->map()->is_observed());
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetPrototype(obj, prototype, false));
+ return *result;
+}
RUNTIME_FUNCTION(Runtime_SetPrototype) {
=======================================
--- /branches/bleeding_edge/src/runtime.h Wed Aug 6 11:39:39 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h Mon Aug 11 14:00:58 2014 UTC
@@ -46,6 +46,7 @@
\
F(GetPrototype, 1, 1) \
F(SetPrototype, 2, 1) \
+ F(InternalSetPrototype, 2, 1) \
F(IsInPrototypeChain, 2, 1) \
\
F(GetOwnProperty, 2, 1) \
=======================================
--- /branches/bleeding_edge/src/serialize.cc Wed Aug 6 07:20:14 2014 UTC
+++ /branches/bleeding_edge/src/serialize.cc Mon Aug 11 14:00:58 2014 UTC
@@ -1338,6 +1338,7 @@
int skip) {
CHECK(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o);
+ DCHECK(!heap_object->IsJSFunction());
int root_index;
if ((root_index = RootIndex(heap_object, how_to_code)) !=
kInvalidRootIndex) {
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Wed Aug 6 13:18:36 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Mon Aug 11 14:00:58 2014 UTC
@@ -349,7 +349,7 @@
CompareNilICStub* stub)
{
Isolate* isolate = receiver_map->GetIsolate();
Handle<String> name(isolate->heap()->empty_string());
- if (!receiver_map->is_shared()) {
+ if (!receiver_map->is_dictionary_map()) {
Handle<Code> cached_ic =
Find(name, receiver_map, Code::COMPARE_NIL_IC,
stub->GetExtraICState());
if (!cached_ic.is_null()) return cached_ic;
@@ -359,7 +359,7 @@
pattern.Add(isolate->factory()->meta_map(), receiver_map);
Handle<Code> ic = stub->GetCodeCopy(pattern);
- if (!receiver_map->is_shared()) {
+ if (!receiver_map->is_dictionary_map()) {
Map::UpdateCodeCache(receiver_map, name, ic);
}
=======================================
--- /branches/bleeding_edge/src/v8natives.js Fri Aug 8 13:39:13 2014 UTC
+++ /branches/bleeding_edge/src/v8natives.js Mon Aug 11 14:00:58 2014 UTC
@@ -96,7 +96,7 @@
%AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE |
READ_ONLY);
%SetNativeFlag(f);
}
- %SetPrototype(prototype, null);
+ %InternalSetPrototype(prototype, null);
%ToFastProperties(prototype);
}
@@ -1125,7 +1125,8 @@
if (!IS_SPEC_OBJECT(proto) && proto !== null) {
throw MakeTypeError("proto_object_or_null", [proto]);
}
- var obj = { __proto__: proto };
+ var obj = {};
+ %InternalSetPrototype(obj, proto);
if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
return obj;
}
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Fri Aug 8
11:42:59 2014 UTC
+++ /branches/bleeding_edge/tools/generate-runtime-tests.py Mon Aug 11
14:00:58 2014 UTC
@@ -47,8 +47,8 @@
# that the parser doesn't bit-rot. Change the values as needed when you
add,
# remove or change runtime functions, but make sure we don't lose our
ability
# to parse them!
-EXPECTED_FUNCTION_COUNT = 427
-EXPECTED_FUZZABLE_COUNT = 330
+EXPECTED_FUNCTION_COUNT = 428
+EXPECTED_FUZZABLE_COUNT = 331
EXPECTED_CCTEST_COUNT = 7
EXPECTED_UNKNOWN_COUNT = 16
EXPECTED_BUILTINS_COUNT = 809
--
--
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.