if (global_object.location() != NULL) {
ASSERT(global_object->IsJSGlobalProxy());
- return ReinitializeJSGlobalProxy(
- global_proxy_function,
- Handle<JSGlobalProxy>::cast(global_object));
+ Handle<JSGlobalProxy> global_proxy =
+ Handle<JSGlobalProxy>::cast(global_object);
+ factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
+ return global_proxy;
} else {
return Handle<JSGlobalProxy>::cast(
factory()->NewJSObject(global_proxy_function, TENURED));
namespace v8 {
namespace internal {
+
+template<typename T>
+Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->Allocate(*map, space),
+ T);
+}
+
+
+template<typename T>
+Handle<T> Factory::New(Handle<Map> map,
+ AllocationSpace space,
+ Handle<AllocationSite> allocation_site) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->Allocate(*map, space, *allocation_site),
+ T);
+}
+
+
Handle<Box> Factory::NewBox(Handle<Object> value) {
Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE));
result->set_value(*value);
Handle<ConsString> Factory::NewRawConsString(String::Encoding encoding) {
Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
? cons_ascii_string_map() : cons_string_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Allocate(*map, NEW_SPACE),
- ConsString);
+ return New<ConsString>(map, NEW_SPACE);
}
// Make sure that an out of memory exception is thrown if the length
// of the new cons string is too large.
if (length > String::kMaxLength || length < 0) {
- return isolate()->Throw<String>(
- isolate()->factory()->NewInvalidStringLengthError());
+ return isolate()->Throw<String>(NewInvalidStringLengthError());
}
bool left_is_one_byte = left->IsOneByteRepresentation();
Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) {
Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
? sliced_ascii_string_map() : sliced_string_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Allocate(*map, NEW_SPACE),
- SlicedString);
+ return New<SlicedString>(map, NEW_SPACE);
}
}
-Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
- Handle<Map> function_map,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateFunction(*function_map,
- *function_info,
- isolate()->heap()->the_hole_value(),
- pretenure),
- JSFunction);
-}
-
-
static Handle<Map> MapForNewFunction(Isolate *isolate,
Handle<SharedFunctionInfo> function_info) {
Context *context = isolate->context()->native_context();
Handle<SharedFunctionInfo> function_info,
Handle<Context> context,
PretenureFlag pretenure) {
- Handle<JSFunction> result = BaseNewFunctionFromSharedFunctionInfo(
- function_info,
+ Handle<JSFunction> result = NewFunctionHelper(
MapForNewFunction(isolate(), function_info),
+ function_info,
+ the_hole_value(),
pretenure);
if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
}
-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());
}
// Allocate the global object and initialize it with the backing store.
- Handle<GlobalObject> global = NewGlobalObjectFromMap(isolate(), map);
+ Handle<GlobalObject> global = New<GlobalObject>(map, OLD_POINTER_SPACE);
isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);
// Create a new map for the global object.
int length,
PretenureFlag pretenure) {
ASSERT(length <= elements->length());
- Handle<JSArray> array =
- isolate()->factory()->NewJSArray(elements_kind, pretenure);
+ Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
array->set_elements(*elements);
array->set_length(Smi::FromInt(length));
}
+void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object,
+ InstanceType type,
+ int size) {
+ ASSERT(type >= FIRST_JS_OBJECT_TYPE);
+
+ // Allocate fresh map.
+ // TODO(rossberg): Once we optimize proxies, cache these maps.
+ Handle<Map> map = NewMap(type, size);
+
+ // Check that the receiver has at least the size of the fresh object.
+ int size_difference = object->map()->instance_size() - map->instance_size();
+ ASSERT(size_difference >= 0);
+
+ map->set_prototype(object->map()->prototype());
+
+ // Allocate the backing storage for the properties.
+ int prop_size = map->unused_property_fields() - map->inobject_properties();
+ Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);
+
+ Heap* heap = isolate()->heap();
+ MaybeHandle<SharedFunctionInfo> shared;
+ if (type == JS_FUNCTION_TYPE) {
+ OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"),
+ heap->HashSeed());
+ Handle<String> name = InternalizeStringWithKey(&key);
+ shared = NewSharedFunctionInfo(name);
+ }
+
+ // In order to keep heap in consistent state there must be no allocations
+ // before object re-initialization is finished and filler object is installed.
+ DisallowHeapAllocation no_allocation;
+
+ // Reset the map for the object.
+ object->set_map(*map);
+ Handle<JSObject> jsobj = Handle<JSObject>::cast(object);
+
+ // Reinitialize the object from the constructor map.
+ heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);
+
+ // Functions require some minimal initialization.
+ if (type == JS_FUNCTION_TYPE) {
+ map->set_function_with_prototype(true);
+ Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
+ InitializeFunction(js_function, shared.ToHandleChecked(), the_hole_value());
+ js_function->set_context(isolate()->context()->native_context());
+ }
+
+ // Put in filler if the new object is smaller than the old.
+ if (size_difference > 0) {
+ heap->CreateFillerObjectAt(
+ object->address() + map->instance_size(), size_difference);
+ }
+}
+
+
+void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
+ Handle<JSFunction> constructor) {
+ ASSERT(constructor->has_initial_map());
+ Handle<Map> map(constructor->initial_map(), isolate());
+
+ // Check that the already allocated object has the same size and type as
+ // objects allocated using the constructor.
+ ASSERT(map->instance_size() == object->map()->instance_size());
+ ASSERT(map->instance_type() == object->map()->instance_type());
+
+ // Allocate the backing storage for the properties.
+ int prop_size = map->unused_property_fields() - map->inobject_properties();
+ Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);
+
+ // In order to keep heap in consistent state there must be no allocations
+ // before object re-initialization is finished.
+ DisallowHeapAllocation no_allocation;
+
+ // Reset the map for the object.
+ object->set_map(constructor->initial_map());
+
+ Heap* heap = isolate()->heap();
+ // Reinitialize the object from the constructor map.
+ heap->InitializeJSObjectFromMap(*object, *properties, *map);
+}
+
+
void Factory::BecomeJSObject(Handle<JSReceiver> object) {
- CALL_HEAP_FUNCTION_VOID(
- isolate(),
- isolate()->heap()->ReinitializeJSReceiver(
- *object, JS_OBJECT_TYPE, JSObject::kHeaderSize));
+ ReinitializeJSReceiver(object, JS_OBJECT_TYPE, JSObject::kHeaderSize);
}
void Factory::BecomeJSFunction(Handle<JSReceiver> object) {
- CALL_HEAP_FUNCTION_VOID(
- isolate(),
- isolate()->heap()->ReinitializeJSReceiver(
- *object, JS_FUNCTION_TYPE, JSFunction::kSize));
+ ReinitializeJSReceiver(object, JS_FUNCTION_TYPE, JSFunction::kSize);
}
}
-Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
- Handle<Object> prototype) {
- Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateFunction(*isolate()->sloppy_function_map(),
- *function_share,
- *prototype),
- JSFunction);
+void Factory::InitializeFunction(Handle<JSFunction> function,
+ Handle<SharedFunctionInfo> shared,
+ Handle<Object> prototype) {
+ ASSERT(!prototype->IsMap());
+ function->initialize_properties();
+ function->initialize_elements();
+ function->set_shared(*shared);
+ function->set_code(shared->code());
+ function->set_prototype_or_initial_map(*prototype);
+ function->set_context(*undefined_value());
+ function->set_literals_or_bindings(*empty_fixed_array());
+ function->set_next_function_link(*undefined_value());
+}
+
+
+Handle<JSFunction> Factory::NewFunctionHelper(Handle<Map> function_map,
+ Handle<SharedFunctionInfo> shared,
+ Handle<Object> prototype,
+ PretenureFlag pretenure) {
+ AllocationSpace space =
+ (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
+ Handle<JSFunction> fun = New<JSFunction>(function_map, space);
+ InitializeFunction(fun, shared, prototype);
+ return fun;
}
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
Handle<Object> prototype) {
- Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
+ Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
+ Handle<JSFunction> fun = NewFunctionHelper(
+ isolate()->sloppy_function_map(), function_share, prototype);
fun->set_context(isolate()->context()->native_context());
return fun;
}
-Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper(
+Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
Handle<String> name,
StrictMode strict_mode) {
Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
Handle<Map> map = strict_mode == SLOPPY
? isolate()->sloppy_function_without_prototype_map()
: isolate()->strict_function_without_prototype_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateFunction(
- *map,
- *function_share,
- *the_hole_value()),
- JSFunction);
-}
-
-
-Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
- Handle<String> name,
- StrictMode strict_mode) {
- Handle<JSFunction> fun = NewFunctionWithoutPrototypeHelper(name, strict_mode);
+ Handle<JSFunction> fun =
+ NewFunctionHelper(map, function_share, the_hole_value());
fun->set_context(isolate()->context()->native_context());
return fun;
}
Handle<Object> construct_trap,
Handle<Object> prototype);
+ // Reinitialize a JSReceiver into an (empty) JS object of respective type and
+ // size, but keeping the original prototype. The receiver must have at least
+ // the size of the new object. The object is reinitialized and behaves as an
+ // object that has been freshly allocated.
+ void ReinitializeJSReceiver(
+ Handle<JSReceiver> object, InstanceType type, int size);
+
+ // Reinitialize an JSGlobalProxy based on a constructor. The object
+ // must have the same size as objects allocated using the
+ // constructor. The object is reinitialized and behaves as an
+ // object that has been freshly allocated using the constructor.
+ void ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> global,
+ Handle<JSFunction> constructor);
+
// Change the type of the argument into a JS object/function and reinitialize.
void BecomeJSObject(Handle<JSReceiver> object);
void BecomeJSFunction(Handle<JSReceiver> object);
Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Object> prototype);
- Handle<JSFunction> NewFunctionWithoutPrototype(
- Handle<String> name,
- StrictMode strict_mode);
-
- Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);
-
- Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
- Handle<Map> function_map,
- PretenureFlag pretenure);
-
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> function_info,
Handle<Context> context,
PretenureFlag pretenure = TENURED);
+ Handle<JSFunction> NewFunction(Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<Code> code,
+ bool force_initial_map);
+
+ Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<JSObject> prototype,
+ Handle<Code> code,
+ bool force_initial_map);
+
+ Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
+ StrictMode strict_mode);
+
+ Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
+ Handle<Code> code);
+
// Create a serialized scope info.
Handle<ScopeInfo> NewScopeInfo(int length);
Handle<Object> NewEvalError(const char* message,
Vector< Handle<Object> > args);
-
- Handle<JSFunction> NewFunction(Handle<String> name,
- InstanceType type,
- int instance_size,
- Handle<Code> code,
- bool force_initial_map);
-
- Handle<JSFunction> NewFunction(Handle<Map> function_map,
- Handle<SharedFunctionInfo> shared, Handle<Object> prototype);
-
-
- Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
- InstanceType type,
- int instance_size,
- Handle<JSObject> prototype,
- Handle<Code> code,
- bool force_initial_map);
-
- Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
- Handle<Code> code);
-
Handle<String> NumberToString(Handle<Object> number,
bool check_number_string_cache = true);
Handle<String> Uint32ToString(uint32_t value);
private:
Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }
- Handle<JSFunction> NewFunctionHelper(Handle<String> name,
- Handle<Object> prototype);
+ // Creates a heap object based on the map. The fields of the heap object are
+ // not initialized by New<>() functions. It's the responsibility of the caller
+ // to do that.
+ template<typename T>
+ Handle<T> New(Handle<Map> map, AllocationSpace space);
+
+ template<typename T>
+ Handle<T> New(Handle<Map> map,
+ AllocationSpace space,
+ Handle<AllocationSite> allocation_site);
+
+ // Initializes a function with a shared part and prototype.
+ // Note: this code was factored out of NewFunctionHelper such that
+ // other parts of the VM could use it. Specifically, a function that creates
+ // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
+ inline void InitializeFunction(Handle<JSFunction> function,
+ Handle<SharedFunctionInfo> shared,
+ Handle<Object> prototype);
- Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
- Handle<String> name,
- StrictMode strict_mode);
+ // Creates a function initialized with a shared part.
+ inline Handle<JSFunction> NewFunctionHelper(
+ Handle<Map> function_map,
+ Handle<SharedFunctionInfo> shared,
+ Handle<Object> prototype,
+ PretenureFlag pretenure = TENURED);
// Create a new map cache.
Handle<MapCache> NewMapCache(int at_least_space_for);
}
-Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
- Handle<JSFunction> constructor,
- Handle<JSGlobalProxy> global) {
- CALL_HEAP_FUNCTION(
- constructor->GetIsolate(),
- constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global),
- JSGlobalProxy);
-}
-
-
MaybeHandle<Object> GetProperty(Handle<JSReceiver> obj,
const char* name) {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
bool cache_result);
-Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
- Handle<JSFunction> constructor,
- Handle<JSGlobalProxy> global);
-
void AddWeakObjectToCodeDependency(Heap* heap,
Handle<Object> object,
Handle<Code> code);
}
-void Heap::InitializeFunction(JSFunction* function,
- SharedFunctionInfo* shared,
- Object* prototype) {
- ASSERT(!prototype->IsMap());
- function->initialize_properties();
- function->initialize_elements();
- function->set_shared(shared);
- function->set_code(shared->code());
- function->set_prototype_or_initial_map(prototype);
- function->set_context(undefined_value());
- function->set_literals_or_bindings(empty_fixed_array());
- function->set_next_function_link(undefined_value());
-}
-
-
-MaybeObject* Heap::AllocateFunction(Map* function_map,
- SharedFunctionInfo* shared,
- Object* prototype,
- PretenureFlag pretenure) {
- AllocationSpace space =
- (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
- Object* result;
- { MaybeObject* maybe_result = Allocate(function_map, space);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- InitializeFunction(JSFunction::cast(result), shared, prototype);
- return result;
-}
-
-
MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
// To get fast allocation and map sharing for arguments objects we
// allocate them based on an arguments boilerplate.
}
-MaybeObject* Heap::ReinitializeJSReceiver(
- JSReceiver* object, InstanceType type, int size) {
- ASSERT(type >= FIRST_JS_OBJECT_TYPE);
-
- // Allocate fresh map.
- // TODO(rossberg): Once we optimize proxies, cache these maps.
- Map* map;
- MaybeObject* maybe = AllocateMap(type, size);
- if (!maybe->To<Map>(&map)) return maybe;
-
- // Check that the receiver has at least the size of the fresh object.
- int size_difference = object->map()->instance_size() - map->instance_size();
- ASSERT(size_difference >= 0);
-
- map->set_prototype(object->map()->prototype());
-
- // Allocate the backing storage for the properties.
- int prop_size = map->unused_property_fields() - map->inobject_properties();
- Object* properties;
- maybe = AllocateFixedArray(prop_size, TENURED);
- if (!maybe->ToObject(&properties)) return maybe;
-
- // Functions require some allocation, which might fail here.
- SharedFunctionInfo* shared = NULL;
- if (type == JS_FUNCTION_TYPE) {
- String* name;
- OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"),
- HashSeed());
- maybe = InternalizeStringWithKey(&key);
- if (!maybe->To<String>(&name)) return maybe;
- maybe = AllocateSharedFunctionInfo(name);
- if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe;
- }
-
- // Because of possible retries of this function after failure,
- // we must NOT fail after this point, where we have changed the type!
-
- // Reset the map for the object.
- object->set_map(map);
- JSObject* jsobj = JSObject::cast(object);
-
- // Reinitialize the object from the constructor map.
- InitializeJSObjectFromMap(jsobj, FixedArray::cast(properties), map);
-
- // Functions require some minimal initialization.
- if (type == JS_FUNCTION_TYPE) {
- map->set_function_with_prototype(true);
- InitializeFunction(JSFunction::cast(object), shared, the_hole_value());
- JSFunction::cast(object)->set_context(
- isolate()->context()->native_context());
- }
-
- // Put in filler if the new object is smaller than the old.
- if (size_difference > 0) {
- CreateFillerObjectAt(
- object->address() + map->instance_size(), size_difference);
- }
-
- return object;
-}
-
-
-MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
- JSGlobalProxy* object) {
- ASSERT(constructor->has_initial_map());
- Map* map = constructor->initial_map();
-
- // Check that the already allocated object has the same size and type as
- // objects allocated using the constructor.
- ASSERT(map->instance_size() == object->map()->instance_size());
- ASSERT(map->instance_type() == object->map()->instance_type());
-
- // Allocate the backing storage for the properties.
- int prop_size = map->unused_property_fields() - map->inobject_properties();
- Object* properties;
- { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, TENURED);
- if (!maybe_properties->ToObject(&properties)) return maybe_properties;
- }
-
- // Reset the map for the object.
- object->set_map(constructor->initial_map());
-
- // Reinitialize the object from the constructor map.
- InitializeJSObjectFromMap(object, FixedArray::cast(properties), map);
- return object;
-}
-
-
MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
PretenureFlag pretenure) {
int length = string.length();
Object* construct_trap,
Object* prototype);
- // Reinitialize a JSReceiver into an (empty) JS object of respective type and
- // size, but keeping the original prototype. The receiver must have at least
- // the size of the new object. The object is reinitialized and behaves as an
- // object that has been freshly allocated.
- // Returns failure if an error occured, otherwise object.
- MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object,
- InstanceType type,
- int size);
-
- // Reinitialize an JSGlobalProxy based on a constructor. The object
- // must have the same size as objects allocated using the
- // constructor. The object is reinitialized and behaves as an
- // object that has been freshly allocated using the constructor.
- MUST_USE_RESULT MaybeObject* ReinitializeJSGlobalProxy(
- JSFunction* constructor, JSGlobalProxy* global);
-
// Allocates and initializes a new JavaScript object based on a map.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Allocates a new utility object in the old generation.
MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
- // Allocates a function initialized with a shared part.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFunction(
- Map* function_map,
- SharedFunctionInfo* shared,
- Object* prototype,
- PretenureFlag pretenure = TENURED);
-
// Sloppy mode arguments object size.
static const int kSloppyArgumentsObjectSize =
JSObject::kHeaderSize + 2 * kPointerSize;
// Slow part of scavenge object.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
- // Initializes a function with a shared part and prototype.
- // Note: this code was factored out of AllocateFunction such that
- // other parts of the VM could use it. Specifically, a function that creates
- // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
- // Please note this does not perform a garbage collection.
- inline void InitializeFunction(
- JSFunction* function,
- SharedFunctionInfo* shared,
- Object* prototype);
-
// Total RegExp code ever generated
double total_regexp_code_generated_;