Function allocators, Heap::ReinitializeJSGlobalProxy() and Heap::ReinitializeJSReceiver() handlified. Factory::New<>() added.
R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/237093006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20762 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
6376579f4d
commit
610fcfa916
@ -766,9 +766,10 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
||||
|
||||
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));
|
||||
|
216
src/factory.cc
216
src/factory.cc
@ -9,6 +9,27 @@
|
||||
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);
|
||||
@ -347,9 +368,7 @@ Handle<String> ConcatStringContent(Handle<StringType> result,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -371,8 +390,7 @@ MaybeHandle<String> Factory::NewConsString(Handle<String> left,
|
||||
// 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();
|
||||
@ -455,9 +473,7 @@ Handle<String> Factory::NewFlatConcatString(Handle<String> first,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -896,20 +912,6 @@ Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
@ -923,9 +925,10 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
||||
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()) {
|
||||
@ -1332,14 +1335,6 @@ Handle<JSModule> Factory::NewJSModule(Handle<Context> context,
|
||||
}
|
||||
|
||||
|
||||
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());
|
||||
@ -1378,7 +1373,7 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -1438,8 +1433,7 @@ Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
||||
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));
|
||||
@ -1566,19 +1560,95 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -1667,46 +1737,52 @@ Handle<UnseededNumberDictionary> Factory::DictionaryAtNumberPut(
|
||||
}
|
||||
|
||||
|
||||
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<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<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
|
||||
Handle<Map> map = strict_mode == SLOPPY
|
||||
? isolate()->sloppy_function_without_prototype_map()
|
||||
: isolate()->strict_function_without_prototype_map();
|
||||
Handle<JSFunction> fun =
|
||||
NewFunctionHelper(map, function_share, the_hole_value());
|
||||
fun->set_context(isolate()->context()->native_context());
|
||||
return fun;
|
||||
}
|
||||
|
@ -393,6 +393,20 @@ class Factory V8_FINAL {
|
||||
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);
|
||||
@ -400,22 +414,30 @@ class Factory V8_FINAL {
|
||||
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);
|
||||
|
||||
@ -470,27 +492,6 @@ class Factory V8_FINAL {
|
||||
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);
|
||||
@ -603,12 +604,31 @@ class Factory V8_FINAL {
|
||||
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);
|
||||
|
||||
Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
|
||||
Handle<String> name,
|
||||
StrictMode strict_mode);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
@ -124,16 +124,6 @@ Address HandleScope::current_limit_address(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
@ -324,10 +324,6 @@ Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length);
|
||||
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);
|
||||
|
118
src/heap.cc
118
src/heap.cc
@ -4093,36 +4093,6 @@ MaybeObject* Heap::Allocate(Map* map, AllocationSpace space,
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
@ -4402,94 +4372,6 @@ MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
36
src/heap.h
36
src/heap.h
@ -735,22 +735,6 @@ class Heap {
|
||||
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.
|
||||
@ -998,16 +982,6 @@ class Heap {
|
||||
// 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;
|
||||
@ -2198,16 +2172,6 @@ class Heap {
|
||||
// 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_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user