| Index: src/factory.cc
|
| diff --git a/src/factory.cc b/src/factory.cc
|
| index 4fb9147e547890d2e61a7e192fb898ca77d5a157..e46d8b598e3499892bebd9a4e623c1fb39e3e292 100644
|
| --- a/src/factory.cc
|
| +++ b/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()) {
|
| @@ -1343,14 +1346,6 @@ static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
|
| }
|
|
|
|
|
| -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());
|
| @@ -1389,7 +1384,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.
|
| @@ -1449,8 +1444,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));
|
| @@ -1565,19 +1559,95 @@ Handle<JSProxy> Factory::NewJSProxy(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);
|
| }
|
|
|
|
|
| @@ -1663,46 +1733,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<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;
|
| }
|
|
|