Revision: 17297
Author: [email protected]
Date: Mon Oct 21 13:55:24 2013 UTC
Log: Handlify PropertyCell::SetValueInferType and friends.
This finally gets rid of the pesky trampoline in SetValueInferType and
enforces the layering between PropertyCell and Heap. It requires full
handlification of NewGlobalObject as well, which is only used when the
snapshot is created at compile-time.
[email protected]
Review URL: https://codereview.chromium.org/28783002
http://code.google.com/p/v8/source/detail?r=17297
Modified:
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/factory.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/stub-cache.cc
=======================================
--- /branches/bleeding_edge/src/factory.cc Mon Oct 14 13:35:06 2013 UTC
+++ /branches/bleeding_edge/src/factory.cc Mon Oct 21 13:55:24 2013 UTC
@@ -538,13 +538,20 @@
}
-Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) {
- AllowDeferredHandleDereference convert_to_cell;
+Handle<PropertyCell> Factory::NewPropertyCellWithHole() {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocatePropertyCell(*value),
+ isolate()->heap()->AllocatePropertyCell(),
PropertyCell);
}
+
+
+Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) {
+ AllowDeferredHandleDereference convert_to_cell;
+ Handle<PropertyCell> cell = NewPropertyCellWithHole();
+ PropertyCell::SetValueInferType(cell, value);
+ return cell;
+}
Handle<AllocationSite> Factory::NewAllocationSite() {
@@ -1052,13 +1059,78 @@
}
-Handle<GlobalObject> Factory::NewGlobalObject(
- Handle<JSFunction> constructor) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateGlobalObject(*constructor),
+// TODO(mstarzinger): Temporary wrapper until handlified.
+static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary>
dict,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyDetails details) {
+ CALL_HEAP_FUNCTION(dict->GetIsolate(),
+ dict->Add(*name, *value, details),
+ NameDictionary);
+}
+
+
+static Handle<GlobalObject> NewGlobalObjectFromMap(Isolate* isolate,
+ Handle<Map> map) {
+ CALL_HEAP_FUNCTION(isolate,
+ isolate->heap()->Allocate(*map, OLD_POINTER_SPACE),
GlobalObject);
}
+
+Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction>
constructor) {
+ ASSERT(constructor->has_initial_map());
+ Handle<Map> map(constructor->initial_map());
+ ASSERT(map->is_dictionary_map());
+
+ // Make sure no field properties are described in the initial map.
+ // This guarantees us that normalizing the properties does not
+ // require us to change property values to PropertyCells.
+ ASSERT(map->NextFreePropertyIndex() == 0);
+
+ // Make sure we don't have a ton of pre-allocated slots in the
+ // global objects. They will be unused once we normalize the object.
+ ASSERT(map->unused_property_fields() == 0);
+ ASSERT(map->inobject_properties() == 0);
+
+ // Initial size of the backing store to avoid resize of the storage
during
+ // bootstrapping. The size differs between the JS global object ad the
+ // builtins object.
+ int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 :
512;
+
+ // Allocate a dictionary object for backing storage.
+ int at_least_space_for = map->NumberOfOwnDescriptors() * 2 +
initial_size;
+ Handle<NameDictionary> dictionary =
NewNameDictionary(at_least_space_for);
+
+ // The global object might be created from an object template with
accessors.
+ // Fill these accessors into the dictionary.
+ Handle<DescriptorArray> descs(map->instance_descriptors());
+ for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
+ PropertyDetails details = descs->GetDetails(i);
+ ASSERT(details.type() == CALLBACKS); // Only accessors are expected.
+ PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i
+ 1);
+ Handle<Name> name(descs->GetKey(i));
+ Handle<Object> value(descs->GetCallbacksObject(i), isolate());
+ Handle<PropertyCell> cell = NewPropertyCell(value);
+ NameDictionaryAdd(dictionary, name, cell, d);
+ }
+
+ // Allocate the global object and initialize it with the backing store.
+ Handle<GlobalObject> global = NewGlobalObjectFromMap(isolate(), map);
+ isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);
+
+ // Create a new map for the global object.
+ Handle<Map> new_map = Map::CopyDropDescriptors(map);
+ new_map->set_dictionary_map(true);
+
+ // Set up the global object as a normalized object.
+ global->set_map(*new_map);
+ global->set_properties(*dictionary);
+
+ // Make sure result is a global object with properties in dictionary.
+ ASSERT(global->IsGlobalObject() && !global->HasFastProperties());
+ return global;
+}
Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map,
=======================================
--- /branches/bleeding_edge/src/factory.h Mon Oct 14 13:35:06 2013 UTC
+++ /branches/bleeding_edge/src/factory.h Mon Oct 21 13:55:24 2013 UTC
@@ -248,6 +248,8 @@
Handle<Cell> NewCell(Handle<Object> value);
+ Handle<PropertyCell> NewPropertyCellWithHole();
+
Handle<PropertyCell> NewPropertyCell(Handle<Object> value);
Handle<AllocationSite> NewAllocationSite();
@@ -306,7 +308,7 @@
Handle<JSObject> NewJSObject(Handle<JSFunction> constructor,
PretenureFlag pretenure = NOT_TENURED);
- // Global objects are pretenured.
+ // Global objects are pretenured and initialized based on a constructor.
Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor);
// JS objects are pretenured when allocated by the bootstrapper and
=======================================
--- /branches/bleeding_edge/src/heap.cc Wed Oct 16 14:47:20 2013 UTC
+++ /branches/bleeding_edge/src/heap.cc Mon Oct 21 13:55:24 2013 UTC
@@ -2963,7 +2963,7 @@
}
-MaybeObject* Heap::AllocatePropertyCell(Object* value) {
+MaybeObject* Heap::AllocatePropertyCell() {
Object* result;
MaybeObject* maybe_result = AllocateRawPropertyCell();
if (!maybe_result->ToObject(&result)) return maybe_result;
@@ -2973,10 +2973,8 @@
PropertyCell* cell = PropertyCell::cast(result);
cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
SKIP_WRITE_BARRIER);
- cell->set_value(value);
+ cell->set_value(the_hole_value());
cell->set_type(Type::None());
- maybe_result = cell->SetValueInferType(value);
- if (maybe_result->IsFailure()) return maybe_result;
return result;
}
@@ -4849,73 +4847,6 @@
result->set_construct_trap(construct_trap);
return result;
}
-
-
-MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
- ASSERT(constructor->has_initial_map());
- Map* map = constructor->initial_map();
- ASSERT(map->is_dictionary_map());
-
- // Make sure no field properties are described in the initial map.
- // This guarantees us that normalizing the properties does not
- // require us to change property values to PropertyCells.
- ASSERT(map->NextFreePropertyIndex() == 0);
-
- // Make sure we don't have a ton of pre-allocated slots in the
- // global objects. They will be unused once we normalize the object.
- ASSERT(map->unused_property_fields() == 0);
- ASSERT(map->inobject_properties() == 0);
-
- // Initial size of the backing store to avoid resize of the storage
during
- // bootstrapping. The size differs between the JS global object ad the
- // builtins object.
- int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 :
512;
-
- // Allocate a dictionary object for backing storage.
- NameDictionary* dictionary;
- MaybeObject* maybe_dictionary =
- NameDictionary::Allocate(
- this,
- map->NumberOfOwnDescriptors() * 2 + initial_size);
- if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
-
- // The global object might be created from an object template with
accessors.
- // Fill these accessors into the dictionary.
- DescriptorArray* descs = map->instance_descriptors();
- for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
- PropertyDetails details = descs->GetDetails(i);
- ASSERT(details.type() == CALLBACKS); // Only accessors are expected.
- PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i
+ 1);
- Object* value = descs->GetCallbacksObject(i);
- MaybeObject* maybe_value = AllocatePropertyCell(value);
- if (!maybe_value->ToObject(&value)) return maybe_value;
-
- MaybeObject* maybe_added = dictionary->Add(descs->GetKey(i), value, d);
- if (!maybe_added->To(&dictionary)) return maybe_added;
- }
-
- // Allocate the global object and initialize it with the backing store.
- JSObject* global;
- MaybeObject* maybe_global = Allocate(map, OLD_POINTER_SPACE);
- if (!maybe_global->To(&global)) return maybe_global;
-
- InitializeJSObjectFromMap(global, dictionary, map);
-
- // Create a new map for the global object.
- Map* new_map;
- MaybeObject* maybe_map = map->CopyDropDescriptors();
- if (!maybe_map->To(&new_map)) return maybe_map;
- new_map->set_dictionary_map(true);
-
- // Set up the global object as a normalized object.
- global->set_map(new_map);
- global->set_properties(dictionary);
-
- // Make sure result is a global object with properties in dictionary.
- ASSERT(global->IsGlobalObject());
- ASSERT(!global->HasFastProperties());
- return global;
-}
MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
=======================================
--- /branches/bleeding_edge/src/heap.h Mon Oct 14 14:00:28 2013 UTC
+++ /branches/bleeding_edge/src/heap.h Mon Oct 21 13:55:24 2013 UTC
@@ -661,12 +661,6 @@
int length,
PretenureFlag pretenure = NOT_TENURED);
- // Allocates and initializes a new global object based on a constructor.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the
allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateGlobalObject(JSFunction*
constructor);
-
// Returns a deep copy of the JavaScript object.
// Properties and elements are copied too.
// Returns failure if allocation failed.
@@ -888,22 +882,6 @@
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateSymbol();
- // Allocate a tenured simple cell.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the
allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateCell(Object* value);
-
- // Allocate a tenured JS global property cell.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the
allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocatePropertyCell(Object* value);
-
- // Allocate Box.
- MUST_USE_RESULT MaybeObject* AllocateBox(Object* value,
- PretenureFlag pretenure);
-
// Allocate a tenured AllocationSite. It's payload is null
MUST_USE_RESULT MaybeObject* AllocateAllocationSite();
@@ -2165,6 +2143,16 @@
// Allocate empty fixed double array.
MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
+ // Allocate a tenured simple cell.
+ MUST_USE_RESULT MaybeObject* AllocateCell(Object* value);
+
+ // Allocate a tenured JS global property cell initialized with the hole.
+ MUST_USE_RESULT MaybeObject* AllocatePropertyCell();
+
+ // Allocate Box.
+ MUST_USE_RESULT MaybeObject* AllocateBox(Object* value,
+ PretenureFlag pretenure);
+
// Performs a minor collection in new generation.
void Scavenge();
=======================================
--- /branches/bleeding_edge/src/objects.cc Fri Oct 18 12:52:07 2013 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Oct 21 13:55:24 2013 UTC
@@ -16310,8 +16310,8 @@
}
-Type* PropertyCell::UpdateType(Handle<PropertyCell> cell,
- Handle<Object> value) {
+Type* PropertyCell::UpdatedType(Handle<PropertyCell> cell,
+ Handle<Object> value) {
Isolate* isolate = cell->GetIsolate();
Handle<Type> old_type(cell->type(), isolate);
// TODO(2803): Do not track ConsString as constant because they cannot be
@@ -16336,27 +16336,12 @@
void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
- Handle<Object> value,
- WriteBarrierMode mode) {
- CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(),
- cell->SetValueInferType(*value, mode));
-}
-
-
-MaybeObject* PropertyCell::SetValueInferType(Object* value,
- WriteBarrierMode ignored) {
- set_value(value, ignored);
- if (!Type::Any()->Is(type())) {
- IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
- MaybeObject* maybe_type = trampoline.CallWithReturnValue(
- &PropertyCell::UpdateType,
- Handle<PropertyCell>(this),
- Handle<Object>(value, GetIsolate()));
- Type* new_type = NULL;
- if (!maybe_type->To(&new_type)) return maybe_type;
- set_type(new_type);
+ Handle<Object> value) {
+ cell->set_value(*value);
+ if (!Type::Any()->Is(cell->type())) {
+ Type* new_type = UpdatedType(cell, value);
+ cell->set_type(new_type);
}
- return value;
}
=======================================
--- /branches/bleeding_edge/src/objects.h Fri Oct 18 12:52:07 2013 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Oct 21 13:55:24 2013 UTC
@@ -9193,11 +9193,17 @@
// a change of the type of the cell's contents, code dependent on the
cell
// will be deoptimized.
static void SetValueInferType(Handle<PropertyCell> cell,
- Handle<Object> value,
- WriteBarrierMode mode =
UPDATE_WRITE_BARRIER);
- MUST_USE_RESULT MaybeObject* SetValueInferType(
- Object* value,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ Handle<Object> value);
+
+ // Computes the new type of the cell's contents for the given value, but
+ // without actually modifying the 'type' field.
+ // TODO(mstarzinger): Return value should be handlified.
+ static Type* UpdatedType(Handle<PropertyCell> cell,
+ Handle<Object> value);
+
+ void AddDependentCompilationInfo(CompilationInfo* info);
+
+ void AddDependentCode(Handle<Code> code);
// Casting.
static inline PropertyCell* cast(Object* obj);
@@ -9222,13 +9228,6 @@
kSize,
kSize> BodyDescriptor;
- void AddDependentCompilationInfo(CompilationInfo* info);
-
- void AddDependentCode(Handle<Code> code);
-
- static Type* UpdateType(Handle<PropertyCell> cell,
- Handle<Object> value);
-
private:
DECL_ACCESSORS(type_raw, Object)
DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Fri Oct 11 14:05:23 2013 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Mon Oct 21 13:55:24 2013 UTC
@@ -268,7 +268,7 @@
Handle<Object> value,
StrictModeFlag strict_mode) {
Isolate* isolate = cell->GetIsolate();
- Handle<Type> union_type(PropertyCell::UpdateType(cell, value), isolate);
+ Handle<Type> union_type(PropertyCell::UpdatedType(cell, value), isolate);
bool is_constant = union_type->IsConstant();
StoreGlobalStub stub(strict_mode, is_constant);
--
--
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/groups/opt_out.