Revert "Only create arguments-maps in the bootstrapper, remove now obsolete ValueType flag."

This reverts commit r22240 for breaking tests on Linux.

Revert "Remove SetOwnPropertyIgnoreAttribute uses from the bootstrapper"

This reverts commit r22241 for breaking tests on Linux.

TBR=verwaest@chromium.org

Review URL: https://codereview.chromium.org/371913002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22242 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
dslomov@chromium.org 2014-07-07 13:12:29 +00:00
parent d400bed3e8
commit 7050e6fa06
16 changed files with 470 additions and 329 deletions

View File

@ -2019,12 +2019,12 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ Allocate(r9, r0, r3, r4, &runtime, TAG_OBJECT);
// r0 = address of new object(s) (tagged)
// r2 = argument count (smi-tagged)
// r2 = argument count (tagged)
// Get the arguments boilerplate from the current native context into r4.
const int kNormalOffset =
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
__ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
@ -2034,23 +2034,22 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// r0 = address of new object (tagged)
// r1 = mapped parameter count (tagged)
// r2 = argument count (smi-tagged)
// r4 = address of arguments map (tagged)
__ str(r4, FieldMemOperand(r0, JSObject::kMapOffset));
__ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex);
__ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset));
__ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
// r2 = argument count (tagged)
// r4 = address of boilerplate object (tagged)
// Copy the JS object part.
for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
__ ldr(r3, FieldMemOperand(r4, i));
__ str(r3, FieldMemOperand(r0, i));
}
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ ldr(r3, MemOperand(sp, 2 * kPointerSize));
__ AssertNotSmi(r3);
const int kCalleeOffset = JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize;
__ str(r3, FieldMemOperand(r0, kCalleeOffset));
// Use the length (smi tagged) and set that as an in-object property too.
__ AssertSmi(r2);
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
const int kLengthOffset = JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize;
@ -2204,18 +2203,15 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the arguments boilerplate from the current native context.
__ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
__ ldr(r4, MemOperand(
r4, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX)));
__ ldr(r4, MemOperand(r4, Context::SlotOffset(
Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX)));
__ str(r4, FieldMemOperand(r0, JSObject::kMapOffset));
__ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex);
__ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset));
__ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
// Copy the JS object part.
__ CopyFields(r0, r4, d0, JSObject::kHeaderSize / kPointerSize);
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
__ ldr(r1, MemOperand(sp, 0 * kPointerSize));
__ AssertSmi(r1);
__ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize));

View File

@ -2103,42 +2103,41 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// Get the arguments boilerplate from the current (global) context.
// x0 alloc_obj pointer to allocated objects (param map, backing
// store, arguments)
// x1 mapped_params number of mapped parameters, min(params, args)
// x2 arg_count number of function arguments
// x3 arg_count_smi number of function arguments (smi)
// x4 function function pointer
// x7 param_count number of function parameters
// x11 sloppy_args_map offset to args (or aliased args) map (uninit)
// x14 recv_arg pointer to receiver arguments
// x0 alloc_obj pointer to allocated objects (param map, backing
// store, arguments)
// x1 mapped_params number of mapped parameters, min(params, args)
// x2 arg_count number of function arguments
// x3 arg_count_smi number of function arguments (smi)
// x4 function function pointer
// x7 param_count number of function parameters
// x11 args_offset offset to args (or aliased args) boilerplate (uninit)
// x14 recv_arg pointer to receiver arguments
Register global_object = x10;
Register global_ctx = x10;
Register sloppy_args_map = x11;
Register aliased_args_map = x10;
Register args_offset = x11;
Register aliased_args_offset = x10;
__ Ldr(global_object, GlobalObjectMemOperand());
__ Ldr(global_ctx, FieldMemOperand(global_object,
GlobalObject::kNativeContextOffset));
__ Ldr(sloppy_args_map,
ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
__ Ldr(aliased_args_map,
ContextMemOperand(global_ctx, Context::ALIASED_ARGUMENTS_MAP_INDEX));
__ Ldr(args_offset,
ContextMemOperand(global_ctx,
Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX));
__ Ldr(aliased_args_offset,
ContextMemOperand(global_ctx,
Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX));
__ Cmp(mapped_params, 0);
__ CmovX(sloppy_args_map, aliased_args_map, ne);
__ CmovX(args_offset, aliased_args_offset, ne);
// Copy the JS object part.
__ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset));
__ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex);
__ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset));
__ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
__ CopyFields(alloc_obj, args_offset, CPURegList(x10, x12, x13),
JSObject::kHeaderSize / kPointerSize);
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
const int kCalleeOffset = JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize;
__ AssertNotSmi(function);
__ Str(function, FieldMemOperand(alloc_obj, kCalleeOffset));
// Use the length and set that as an in-object property.
@ -2339,24 +2338,25 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the arguments boilerplate from the current (native) context.
Register global_object = x10;
Register global_ctx = x10;
Register strict_args_map = x4;
Register args_offset = x4;
__ Ldr(global_object, GlobalObjectMemOperand());
__ Ldr(global_ctx, FieldMemOperand(global_object,
GlobalObject::kNativeContextOffset));
__ Ldr(strict_args_map,
ContextMemOperand(global_ctx, Context::STRICT_ARGUMENTS_MAP_INDEX));
__ Ldr(args_offset,
ContextMemOperand(global_ctx,
Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX));
// x0 alloc_obj pointer to allocated objects: parameter array and
// arguments object
// x1 param_count_smi number of parameters passed to function (smi)
// x2 params pointer to parameters
// x3 function function pointer
// x4 strict_args_map offset to arguments map
// x4 args_offset offset to arguments boilerplate
// x13 param_count number of parameters passed to function
__ Str(strict_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset));
__ LoadRoot(x5, Heap::kEmptyFixedArrayRootIndex);
__ Str(x5, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset));
__ Str(x5, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
// Copy the JS object part.
__ CopyFields(alloc_obj, args_offset, CPURegList(x5, x6, x7),
JSObject::kHeaderSize / kPointerSize);
// Set the smi-tagged length as an in-object property.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);

View File

@ -769,17 +769,16 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
Handle<String> name = Handle<String>(heap()->empty_string());
Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Builtins::kIllegal));
Handle<JSObject> prototype =
factory()->NewFunctionPrototype(isolate()->object_function());
js_global_object_function = factory()->NewFunction(
name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
#ifdef DEBUG
LookupIterator it(prototype, factory()->constructor_string(),
LookupIterator::CHECK_OWN_REAL);
Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked();
ASSERT(it.IsFound());
ASSERT_EQ(*isolate()->object_function(), *value);
#endif
name, code, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
// Change the constructor property of the prototype of the
// hidden global function to refer to the Object function.
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_object_function->instance_prototype()));
JSObject::SetOwnPropertyIgnoreAttributes(
prototype, factory()->constructor_string(),
isolate()->object_function(), NONE).Check();
} else {
Handle<FunctionTemplateInfo> js_global_object_constructor(
FunctionTemplateInfo::cast(js_global_object_template->constructor()));
@ -1134,57 +1133,80 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
isolate->initial_object_prototype(), Builtins::kIllegal);
{ // --- sloppy arguments map
{ // --- arguments_boilerplate_
// Make sure we can recognize argument objects at runtime.
// This is done by introducing an anonymous function with
// class_name equals 'Arguments'.
Handle<String> arguments_string = factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("Arguments"));
Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
arguments_string, code);
function->shared()->set_instance_class_name(*arguments_string);
Handle<Map> map =
factory->NewMap(JS_OBJECT_TYPE, Heap::kSloppyArgumentsObjectSize);
// Create the descriptor array for the arguments object.
Map::EnsureDescriptorSlack(map, 2);
{ // length
FieldDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
DONT_ENUM, Representation::Tagged());
map->AppendDescriptor(&d);
}
{ // callee
FieldDescriptor d(factory->callee_string(), Heap::kArgumentsCalleeIndex,
DONT_ENUM, Representation::Tagged());
map->AppendDescriptor(&d);
}
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);
ASSERT(!function->has_initial_map());
function->set_initial_map(*map);
map->set_constructor(*function);
function->shared()->set_instance_class_name(*arguments_string);
function->shared()->set_expected_nof_properties(2);
function->set_prototype_or_initial_map(
native_context()->object_function()->prototype());
Handle<JSObject> result = factory->NewJSObject(function);
ASSERT(map->inobject_properties() > Heap::kArgumentsCalleeIndex);
ASSERT(map->inobject_properties() > Heap::kArgumentsLengthIndex);
ASSERT(!map->is_dictionary_map());
ASSERT(IsFastObjectElementsKind(map->elements_kind()));
native_context()->set_sloppy_arguments_boilerplate(*result);
// Note: length must be added as the first property and
// callee must be added as the second property.
JSObject::AddProperty(
result, factory->length_string(),
factory->undefined_value(), DONT_ENUM,
Object::FORCE_TAGGED, FORCE_FIELD);
JSObject::AddProperty(
result, factory->callee_string(),
factory->undefined_value(), DONT_ENUM,
Object::FORCE_TAGGED, FORCE_FIELD);
#ifdef DEBUG
LookupResult lookup(isolate);
result->LookupOwn(factory->callee_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().property_index() ==
Heap::kArgumentsCalleeIndex);
result->LookupOwn(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().property_index() ==
Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
// Check the state of the object.
ASSERT(result->HasFastProperties());
ASSERT(result->HasFastObjectElements());
#endif
}
{ // --- aliased arguments map
Handle<Map> map = Map::Copy(isolate->sloppy_arguments_map());
map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
ASSERT_EQ(2, map->pre_allocated_property_fields());
native_context()->set_aliased_arguments_map(*map);
{ // --- aliased_arguments_boilerplate_
// Set up a well-formed parameter map to make assertions happy.
Handle<FixedArray> elements = factory->NewFixedArray(2);
elements->set_map(heap->sloppy_arguments_elements_map());
Handle<FixedArray> array;
array = factory->NewFixedArray(0);
elements->set(0, *array);
array = factory->NewFixedArray(0);
elements->set(1, *array);
Handle<Map> old_map(
native_context()->sloppy_arguments_boilerplate()->map());
Handle<Map> new_map = Map::Copy(old_map);
new_map->set_pre_allocated_property_fields(2);
Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
// Set elements kind after allocating the object because
// NewJSObjectFromMap assumes a fast elements map.
new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
result->set_elements(*elements);
ASSERT(result->HasSloppyArgumentsElements());
native_context()->set_aliased_arguments_boilerplate(*result);
}
{ // --- strict mode arguments map
{ // --- strict mode arguments boilerplate
const PropertyAttributes attributes =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
@ -1207,16 +1229,20 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
Map::EnsureDescriptorSlack(map, 3);
{ // length
FieldDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
DONT_ENUM, Representation::Tagged());
FieldDescriptor d(
factory->length_string(), 0, DONT_ENUM, Representation::Tagged());
map->AppendDescriptor(&d);
}
{ // callee
CallbacksDescriptor d(factory->callee_string(), callee, attributes);
CallbacksDescriptor d(factory->callee_string(),
callee,
attributes);
map->AppendDescriptor(&d);
}
{ // caller
CallbacksDescriptor d(factory->caller_string(), caller, attributes);
CallbacksDescriptor d(factory->caller_string(),
caller,
attributes);
map->AppendDescriptor(&d);
}
@ -1227,13 +1253,29 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
// Copy constructor from the sloppy arguments boilerplate.
map->set_constructor(
native_context()->sloppy_arguments_map()->constructor());
native_context()->sloppy_arguments_boilerplate()->map()->constructor());
native_context()->set_strict_arguments_map(*map);
// Allocate the arguments boilerplate object.
Handle<JSObject> result = factory->NewJSObjectFromMap(map);
native_context()->set_strict_arguments_boilerplate(*result);
ASSERT(map->inobject_properties() > Heap::kArgumentsLengthIndex);
ASSERT(!map->is_dictionary_map());
ASSERT(IsFastObjectElementsKind(map->elements_kind()));
#ifdef DEBUG
LookupResult lookup(isolate);
result->LookupOwn(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().property_index() ==
Heap::kArgumentsLengthIndex);
Handle<Object> length_value = Object::GetProperty(
result, factory->length_string()).ToHandleChecked();
ASSERT_EQ(heap->undefined_value(), *length_value);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
// Check the state of the object.
ASSERT(result->HasFastProperties());
ASSERT(result->HasFastObjectElements());
#endif
}
{ // --- context extension
@ -2150,34 +2192,45 @@ bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
Isolate* isolate = native_context->GetIsolate();
// Don't install extensions into the snapshot.
if (isolate->serializer_enabled()) return true;
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<JSGlobalObject> global(JSGlobalObject::cast(
native_context->global_object()));
Handle<JSObject> Error = Handle<JSObject>::cast(
Object::GetProperty(isolate, global, "Error").ToHandleChecked());
Handle<String> name =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("stackTraceLimit"));
Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
// Expose the natives in global if a name for it is specified.
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
Handle<String> natives =
factory->InternalizeUtf8String(FLAG_expose_natives_as);
JSObject::AddProperty(global, natives, handle(global->builtins()),
DONT_ENUM);
RETURN_ON_EXCEPTION_VALUE(
isolate,
JSObject::SetOwnPropertyIgnoreAttributes(
global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM),
false);
}
Handle<Object> Error = Object::GetProperty(
isolate, global, "Error").ToHandleChecked();
if (Error->IsJSObject()) {
Handle<String> name = factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("stackTraceLimit"));
Handle<Smi> stack_trace_limit(
Smi::FromInt(FLAG_stack_trace_limit), isolate);
RETURN_ON_EXCEPTION_VALUE(
isolate,
JSObject::SetOwnPropertyIgnoreAttributes(
Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE),
false);
}
// Expose the stack trace symbol to native JS.
JSObject::AddProperty(handle(global->builtins()),
factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("stack_trace_symbol")),
factory->stack_trace_symbol(), NONE);
RETURN_ON_EXCEPTION_VALUE(
isolate,
JSObject::SetOwnPropertyIgnoreAttributes(
handle(native_context->builtins(), isolate),
factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("stack_trace_symbol")),
factory->stack_trace_symbol(),
NONE),
false);
// Expose the debug global object in global if a name for it is specified.
if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
@ -2193,7 +2246,11 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
Handle<String> debug_string =
factory->InternalizeUtf8String(FLAG_expose_debug_as);
Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
RETURN_ON_EXCEPTION_VALUE(
isolate,
JSObject::SetOwnPropertyIgnoreAttributes(
global, debug_string, global_proxy, DONT_ENUM),
false);
}
return true;
}

View File

@ -643,8 +643,8 @@ BUILTIN(ArraySlice) {
} else {
// Array.slice(arguments, ...) is quite a common idiom (notably more
// than 50% of invocations in Web apps). Treat it in C++ as well.
Map* arguments_map =
isolate->context()->native_context()->sloppy_arguments_map();
Map* arguments_map = isolate->context()->native_context()->
sloppy_arguments_boilerplate()->map();
bool is_arguments_object_with_fast_elements =
receiver->IsJSObject() &&

View File

@ -73,114 +73,122 @@ enum BindingFlags {
// must always be allocated via Heap::AllocateContext() or
// Factory::NewContext.
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps) \
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
V(JSON_OBJECT_INDEX, JSObject, json_object) \
V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype) \
V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun) \
V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun) \
V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) \
V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
V(TO_OBJECT_FUN_INDEX, JSFunction, to_object_fun) \
V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \
V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \
V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun) \
V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun) \
V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \
V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \
V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun) \
V(UINT32_ARRAY_FUN_INDEX, JSFunction, uint32_array_fun) \
V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun) \
V(FLOAT32_ARRAY_FUN_INDEX, JSFunction, float32_array_fun) \
V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun) \
V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
V(INT8_ARRAY_EXTERNAL_MAP_INDEX, Map, int8_array_external_map) \
V(UINT8_ARRAY_EXTERNAL_MAP_INDEX, Map, uint8_array_external_map) \
V(INT16_ARRAY_EXTERNAL_MAP_INDEX, Map, int16_array_external_map) \
V(UINT16_ARRAY_EXTERNAL_MAP_INDEX, Map, uint16_array_external_map) \
V(INT32_ARRAY_EXTERNAL_MAP_INDEX, Map, int32_array_external_map) \
V(UINT32_ARRAY_EXTERNAL_MAP_INDEX, Map, uint32_array_external_map) \
V(FLOAT32_ARRAY_EXTERNAL_MAP_INDEX, Map, float32_array_external_map) \
V(FLOAT64_ARRAY_EXTERNAL_MAP_INDEX, Map, float64_array_external_map) \
V(UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX, Map, \
uint8_clamped_array_external_map) \
V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \
V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_without_prototype_map) \
V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
strict_function_without_prototype_map) \
V(BOUND_FUNCTION_MAP_INDEX, Map, bound_function_map) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
V(SLOPPY_ARGUMENTS_MAP_INDEX, Map, sloppy_arguments_map) \
V(ALIASED_ARGUMENTS_MAP_INDEX, Map, aliased_arguments_map) \
V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map) \
V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \
V(FUNCTION_CACHE_INDEX, JSObject, function_cache) \
V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches) \
V(NORMALIZED_MAP_CACHE_INDEX, NormalizedMapCache, normalized_map_cache) \
V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \
V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
call_as_constructor_delegate) \
V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
V(IS_PROMISE_INDEX, JSFunction, is_promise) \
V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
V(PROMISE_RESOLVE_INDEX, JSFunction, promise_resolve) \
V(PROMISE_REJECT_INDEX, JSFunction, promise_reject) \
V(PROMISE_CHAIN_INDEX, JSFunction, promise_chain) \
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
V(PROXY_ENUMERATE_INDEX, JSFunction, proxy_enumerate) \
V(OBSERVERS_NOTIFY_CHANGE_INDEX, JSFunction, observers_notify_change) \
V(OBSERVERS_ENQUEUE_SPLICE_INDEX, JSFunction, observers_enqueue_splice) \
V(OBSERVERS_BEGIN_SPLICE_INDEX, JSFunction, observers_begin_perform_splice) \
V(OBSERVERS_END_SPLICE_INDEX, JSFunction, observers_end_perform_splice) \
V(NATIVE_OBJECT_OBSERVE_INDEX, JSFunction, native_object_observe) \
V(NATIVE_OBJECT_GET_NOTIFIER_INDEX, JSFunction, native_object_get_notifier) \
V(NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE, JSFunction, \
native_object_notifier_perform_change) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map) \
V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, generator_object_prototype_map) \
V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \
V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map) \
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps) \
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
V(JSON_OBJECT_INDEX, JSObject, json_object) \
V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype) \
V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun) \
V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun) \
V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) \
V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
V(TO_OBJECT_FUN_INDEX, JSFunction, to_object_fun) \
V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \
V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \
V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun) \
V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun) \
V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \
V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \
V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun) \
V(UINT32_ARRAY_FUN_INDEX, JSFunction, uint32_array_fun) \
V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun) \
V(FLOAT32_ARRAY_FUN_INDEX, JSFunction, float32_array_fun) \
V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun) \
V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
V(INT8_ARRAY_EXTERNAL_MAP_INDEX, Map, int8_array_external_map) \
V(UINT8_ARRAY_EXTERNAL_MAP_INDEX, Map, uint8_array_external_map) \
V(INT16_ARRAY_EXTERNAL_MAP_INDEX, Map, int16_array_external_map) \
V(UINT16_ARRAY_EXTERNAL_MAP_INDEX, Map, uint16_array_external_map) \
V(INT32_ARRAY_EXTERNAL_MAP_INDEX, Map, int32_array_external_map) \
V(UINT32_ARRAY_EXTERNAL_MAP_INDEX, Map, uint32_array_external_map) \
V(FLOAT32_ARRAY_EXTERNAL_MAP_INDEX, Map, float32_array_external_map) \
V(FLOAT64_ARRAY_EXTERNAL_MAP_INDEX, Map, float64_array_external_map) \
V(UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX, Map, \
uint8_clamped_array_external_map) \
V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \
V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_without_prototype_map) \
V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
strict_function_without_prototype_map) \
V(BOUND_FUNCTION_MAP_INDEX, Map, bound_function_map) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
V(SLOPPY_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
sloppy_arguments_boilerplate) \
V(ALIASED_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
aliased_arguments_boilerplate) \
V(STRICT_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
strict_arguments_boilerplate) \
V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \
V(FUNCTION_CACHE_INDEX, JSObject, function_cache) \
V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches) \
V(NORMALIZED_MAP_CACHE_INDEX, NormalizedMapCache, normalized_map_cache) \
V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \
V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
call_as_constructor_delegate) \
V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
V(IS_PROMISE_INDEX, JSFunction, is_promise) \
V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
V(PROMISE_RESOLVE_INDEX, JSFunction, promise_resolve) \
V(PROMISE_REJECT_INDEX, JSFunction, promise_reject) \
V(PROMISE_CHAIN_INDEX, JSFunction, promise_chain) \
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
V(PROXY_ENUMERATE_INDEX, JSFunction, proxy_enumerate) \
V(OBSERVERS_NOTIFY_CHANGE_INDEX, JSFunction, observers_notify_change) \
V(OBSERVERS_ENQUEUE_SPLICE_INDEX, JSFunction, observers_enqueue_splice) \
V(OBSERVERS_BEGIN_SPLICE_INDEX, JSFunction, \
observers_begin_perform_splice) \
V(OBSERVERS_END_SPLICE_INDEX, JSFunction, \
observers_end_perform_splice) \
V(NATIVE_OBJECT_OBSERVE_INDEX, JSFunction, \
native_object_observe) \
V(NATIVE_OBJECT_GET_NOTIFIER_INDEX, JSFunction, \
native_object_get_notifier) \
V(NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE, JSFunction, \
native_object_notifier_perform_change) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map) \
V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
generator_object_prototype_map) \
V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \
V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map) \
V(ITERATOR_SYMBOL_INDEX, Symbol, iterator_symbol)
// JSFunctions are pairs (context, function code), sometimes also called
@ -255,9 +263,9 @@ class Context: public FixedArray {
// These slots are only in native contexts.
GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
SECURITY_TOKEN_INDEX,
SLOPPY_ARGUMENTS_MAP_INDEX,
ALIASED_ARGUMENTS_MAP_INDEX,
STRICT_ARGUMENTS_MAP_INDEX,
SLOPPY_ARGUMENTS_BOILERPLATE_INDEX,
ALIASED_ARGUMENTS_BOILERPLATE_INDEX,
STRICT_ARGUMENTS_BOILERPLATE_INDEX,
REGEXP_RESULT_MAP_INDEX,
SLOPPY_FUNCTION_MAP_INDEX,
SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX,
@ -367,6 +375,7 @@ class Context: public FixedArray {
// Total number of slots.
NATIVE_CONTEXT_SLOTS,
FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
};

View File

@ -4,7 +4,6 @@
#include "src/factory.h"
#include "src/allocation-site-scopes.h"
#include "src/conversions.h"
#include "src/isolate-inl.h"
#include "src/macro-assembler.h"
@ -2087,24 +2086,11 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
}
Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
int length) {
bool strict_mode_callee = callee->shared()->strict_mode() == STRICT;
Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map()
: isolate()->sloppy_arguments_map();
AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
false);
ASSERT(!isolate()->has_pending_exception());
Handle<JSObject> result = NewJSObjectFromMap(map);
Handle<Smi> value(Smi::FromInt(length), isolate());
JSReceiver::SetProperty(result, length_string(), value, NONE, STRICT)
.Assert();
if (!strict_mode_callee) {
JSReceiver::SetProperty(result, callee_string(), callee, NONE, STRICT)
.Assert();
}
return result;
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject);
}

View File

@ -361,7 +361,7 @@ class Factory V8_FINAL {
return NewJSObjectFromMap(neander_map());
}
Handle<JSObject> NewArgumentsObject(Handle<JSFunction> callee, int length);
Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length);
// JS objects are pretenured when allocated by the bootstrapper and
// runtime.

View File

@ -3569,6 +3569,58 @@ AllocationResult Heap::Allocate(Map* map, AllocationSpace space,
}
AllocationResult Heap::AllocateArgumentsObject(Object* callee, int length) {
// To get fast allocation and map sharing for arguments objects we
// allocate them based on an arguments boilerplate.
JSObject* boilerplate;
int arguments_object_size;
bool strict_mode_callee = callee->IsJSFunction() &&
JSFunction::cast(callee)->shared()->strict_mode() == STRICT;
if (strict_mode_callee) {
boilerplate =
isolate()->context()->native_context()->strict_arguments_boilerplate();
arguments_object_size = kStrictArgumentsObjectSize;
} else {
boilerplate =
isolate()->context()->native_context()->sloppy_arguments_boilerplate();
arguments_object_size = kSloppyArgumentsObjectSize;
}
// Check that the size of the boilerplate matches our
// expectations. The ArgumentsAccessStub::GenerateNewObject relies
// on the size being a known constant.
ASSERT(arguments_object_size == boilerplate->map()->instance_size());
// Do the allocation.
HeapObject* result;
{ AllocationResult allocation =
AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE);
if (!allocation.To(&result)) return allocation;
}
// Copy the content. The arguments boilerplate doesn't have any
// fields that point to new space so it's safe to skip the write
// barrier here.
CopyBlock(result->address(), boilerplate->address(), JSObject::kHeaderSize);
// Set the length property.
JSObject* js_obj = JSObject::cast(result);
js_obj->InObjectPropertyAtPut(
kArgumentsLengthIndex, Smi::FromInt(length), SKIP_WRITE_BARRIER);
// Set the callee property for sloppy mode arguments object only.
if (!strict_mode_callee) {
js_obj->InObjectPropertyAtPut(kArgumentsCalleeIndex, callee);
}
// Check the state of the object
ASSERT(js_obj->HasFastProperties());
ASSERT(js_obj->HasFastObjectElements());
return js_obj;
}
void Heap::InitializeJSObjectFromMap(JSObject* obj,
FixedArray* properties,
Map* map) {

View File

@ -1486,6 +1486,10 @@ class Heap {
int length,
PretenureFlag pretenure = NOT_TENURED);
// Allocates an arguments object - optionally with an elements array.
MUST_USE_RESULT AllocationResult AllocateArgumentsObject(
Object* callee, int length);
// Copy the code and scope info part of the code object, but insert
// the provided data as the relocation information.
MUST_USE_RESULT AllocationResult CopyCode(Code* code,

View File

@ -1036,7 +1036,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ mov(Operand(esp, 2 * kPointerSize), edx);
// ebx = parameter count (tagged)
// ecx = argument count (smi-tagged)
// ecx = argument count (tagged)
// esp[4] = parameter count (tagged)
// esp[8] = address of receiver argument
// Compute the mapped parameter count = min(ebx, ecx) in ebx.
@ -1069,52 +1069,47 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
// eax = address of new object(s) (tagged)
// ecx = argument count (smi-tagged)
// ecx = argument count (tagged)
// esp[0] = mapped parameter count (tagged)
// esp[8] = parameter count (tagged)
// esp[12] = address of receiver argument
// Get the arguments map from the current native context into edi.
Label has_mapped_parameters, instantiate;
// Get the arguments boilerplate from the current native context into edi.
Label has_mapped_parameters, copy;
__ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
__ mov(ebx, Operand(esp, 0 * kPointerSize));
__ test(ebx, ebx);
__ j(not_zero, &has_mapped_parameters, Label::kNear);
__ mov(
edi,
Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
__ jmp(&instantiate, Label::kNear);
__ mov(edi, Operand(edi,
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX)));
__ jmp(&copy, Label::kNear);
__ bind(&has_mapped_parameters);
__ mov(
edi,
Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX)));
__ bind(&instantiate);
__ mov(edi, Operand(edi,
Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX)));
__ bind(&copy);
// eax = address of new object (tagged)
// ebx = mapped parameter count (tagged)
// ecx = argument count (smi-tagged)
// edi = address of arguments map (tagged)
// ecx = argument count (tagged)
// edi = address of boilerplate object (tagged)
// esp[0] = mapped parameter count (tagged)
// esp[8] = parameter count (tagged)
// esp[12] = address of receiver argument
// Copy the JS object part.
__ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
masm->isolate()->factory()->empty_fixed_array());
__ mov(FieldOperand(eax, JSObject::kElementsOffset),
masm->isolate()->factory()->empty_fixed_array());
for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
__ mov(edx, FieldOperand(edi, i));
__ mov(FieldOperand(eax, i), edx);
}
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ mov(edx, Operand(esp, 4 * kPointerSize));
__ AssertNotSmi(edx);
__ mov(FieldOperand(eax, JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize),
edx);
// Use the length (smi tagged) and set that as an in-object property too.
__ AssertSmi(ecx);
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
__ mov(FieldOperand(eax, JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize),
@ -1271,22 +1266,22 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Do the allocation of both objects in one go.
__ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
// Get the arguments map from the current native context.
// Get the arguments boilerplate from the current native context.
__ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
const int offset =
Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX);
__ mov(edi, Operand(edi, offset));
__ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
masm->isolate()->factory()->empty_fixed_array());
__ mov(FieldOperand(eax, JSObject::kElementsOffset),
masm->isolate()->factory()->empty_fixed_array());
// Copy the JS object part.
for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
__ mov(ebx, FieldOperand(edi, i));
__ mov(FieldOperand(eax, i), ebx);
}
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
__ mov(ecx, Operand(esp, 1 * kPointerSize));
__ AssertSmi(ecx);
__ mov(FieldOperand(eax, JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize),
ecx);

View File

@ -1834,6 +1834,7 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
ValueType value_type,
TransitionFlag flag) {
ASSERT(!object->IsJSGlobalProxy());
@ -1843,7 +1844,7 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
handle(object->map()), name, value, attributes, flag);
} else if (!object->TooManyFastProperties(store_mode)) {
Isolate* isolate = object->GetIsolate();
Representation representation = value->OptimalRepresentation();
Representation representation = value->OptimalRepresentation(value_type);
maybe_map = Map::CopyWithField(
handle(object->map(), isolate), name,
value->OptimalType(isolate, representation),
@ -1900,6 +1901,7 @@ MaybeHandle<Object> JSObject::AddPropertyInternal(
StrictMode strict_mode,
JSReceiver::StoreFromKeyed store_mode,
ExtensibilityCheck extensibility_check,
ValueType value_type,
StoreMode mode,
TransitionFlag transition_flag) {
ASSERT(!object->IsJSGlobalProxy());
@ -1924,7 +1926,7 @@ MaybeHandle<Object> JSObject::AddPropertyInternal(
if (object->HasFastProperties()) {
AddFastProperty(object, name, value, attributes, store_mode,
transition_flag);
value_type, transition_flag);
}
if (!object->HasFastProperties()) {
@ -3974,7 +3976,8 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
return JSObject::AddPropertyInternal(
object, name, value, attributes, SLOPPY,
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
JSReceiver::OMIT_EXTENSIBILITY_CHECK, FORCE_FIELD, OMIT_TRANSITION);
JSReceiver::OMIT_EXTENSIBILITY_CHECK,
JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
}
// Keep the target CONSTANT if the same value is stored.
@ -4220,6 +4223,7 @@ void JSObject::AddProperty(
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type,
StoreMode store_mode) {
#ifdef DEBUG
uint32_t index;
@ -4230,8 +4234,9 @@ void JSObject::AddProperty(
ASSERT(!it.IsFound());
ASSERT(object->map()->is_extensible());
#endif
SetOwnPropertyIgnoreAttributes(object, name, value, attributes, store_mode,
OMIT_EXTENSIBILITY_CHECK).Check();
SetOwnPropertyIgnoreAttributes(
object, name, value, attributes, value_type, store_mode,
OMIT_EXTENSIBILITY_CHECK).Check();
}
@ -4246,6 +4251,7 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type,
StoreMode mode,
ExtensibilityCheck extensibility_check,
StoreFromKeyed store_from_keyed,
@ -4274,9 +4280,8 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
Handle<Object> proto(object->GetPrototype(), isolate);
if (proto->IsNull()) return value;
ASSERT(proto->IsJSGlobalObject());
return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), name,
value, attributes, mode,
extensibility_check);
return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
name, value, attributes, value_type, mode, extensibility_check);
}
if (lookup.IsInterceptor() ||
@ -4291,8 +4296,7 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
? OMIT_TRANSITION : INSERT_TRANSITION;
// Neither properties nor transitions found.
return AddPropertyInternal(object, name, value, attributes, SLOPPY,
store_from_keyed, extensibility_check, mode,
flag);
store_from_keyed, extensibility_check, value_type, mode, flag);
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
@ -5256,8 +5260,12 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
}
}
SetOwnPropertyIgnoreAttributes(object, isolate->factory()->hidden_string(),
value, DONT_ENUM, ALLOW_AS_CONSTANT,
SetOwnPropertyIgnoreAttributes(object,
isolate->factory()->hidden_string(),
value,
DONT_ENUM,
OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT,
OMIT_EXTENSIBILITY_CHECK).Assert();
return object;
}
@ -5602,10 +5610,11 @@ bool JSObject::ReferencesObject(Object* obj) {
// For functions check the context.
if (IsJSFunction()) {
// Get the constructor function for arguments array.
Map* arguments_map =
heap->isolate()->context()->native_context()->sloppy_arguments_map();
JSObject* arguments_boilerplate =
heap->isolate()->context()->native_context()->
sloppy_arguments_boilerplate();
JSFunction* arguments_function =
JSFunction::cast(arguments_map->constructor());
JSFunction::cast(arguments_boilerplate->map()->constructor());
// Get the context and don't check if it is the native context.
JSFunction* f = JSFunction::cast(this);
@ -5897,7 +5906,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
Handle<JSObject> object) {
Isolate* isolate = this->isolate();
bool copying = this->copying();
bool shallow = hints_ == JSObject::kObjectIsShallow;
bool shallow = hints_ == JSObject::kObjectIsShallowArray;
if (!shallow) {
StackLimitCheck check(isolate);
@ -6384,8 +6393,12 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
USE(ContainsOnlyValidKeys);
Isolate* isolate = object->GetIsolate();
Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
Handle<JSFunction> arguments_function(
JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
isolate->context()->native_context()->sloppy_arguments_boilerplate(),
isolate);
Handle<JSFunction> arguments_function = Handle<JSFunction>(
JSFunction::cast(arguments_boilerplate->map()->constructor()),
isolate);
// Only collect keys if access is permitted.
for (Handle<Object> p = object;

View File

@ -1406,8 +1406,17 @@ class Object {
bool ToInt32(int32_t* value);
bool ToUint32(uint32_t* value);
inline Representation OptimalRepresentation() {
// Indicates whether OptimalRepresentation can do its work, or whether it
// always has to return Representation::Tagged().
enum ValueType {
OPTIMAL_REPRESENTATION,
FORCE_TAGGED
};
inline Representation OptimalRepresentation(
ValueType type = OPTIMAL_REPRESENTATION) {
if (!FLAG_track_fields) return Representation::Tagged();
if (type == FORCE_TAGGED) return Representation::Tagged();
if (IsSmi()) {
return Representation::Smi();
} else if (FLAG_track_double_fields && IsHeapNumber()) {
@ -2158,6 +2167,7 @@ class JSObject: public JSReceiver {
Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT,
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
@ -2167,6 +2177,7 @@ class JSObject: public JSReceiver {
Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT);
// Extend the receiver with a single fast property appeared first in the
@ -2506,7 +2517,10 @@ class JSObject: public JSReceiver {
static void SetObserved(Handle<JSObject> object);
// Copy object.
enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
enum DeepCopyHints {
kNoHints = 0,
kObjectIsShallowArray = 1
};
static Handle<JSObject> Copy(Handle<JSObject> object);
MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
@ -2771,6 +2785,7 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT,
TransitionFlag flag = INSERT_TRANSITION);
@ -2780,6 +2795,7 @@ class JSObject: public JSReceiver {
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
ValueType value_type,
TransitionFlag flag);
// Add a property to a slow-case object.

View File

@ -251,6 +251,9 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
JSObject::NormalizeProperties(
boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
}
Object::ValueType value_type = should_normalize
? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION;
// TODO(verwaest): Support tracking representations in the boilerplate.
for (int index = 0; index < length; index +=2) {
Handle<Object> key(constant_properties->get(index+0), isolate);
@ -280,7 +283,8 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
Handle<String> name(String::cast(*key));
ASSERT(!name->AsArrayIndex(&element_index));
maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
boilerplate, name, value, NONE, mode);
boilerplate, name, value, NONE,
value_type, mode);
}
} else if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
@ -299,7 +303,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
const char* str = DoubleToCString(num, buffer);
Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
boilerplate, name, value, NONE, mode);
boilerplate, name, value, NONE, value_type, mode);
}
// If setting the property on the boilerplate throws an
// exception, the exception is converted to an empty handle in
@ -568,8 +572,8 @@ static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
usage_context.EnterNewScope();
JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
? JSObject::kNoHints
: JSObject::kObjectIsShallow;
? JSObject::kNoHints
: JSObject::kObjectIsShallowArray;
MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
hints);
usage_context.ExitScope(site, boilerplate);
@ -5089,6 +5093,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
isolate, result,
JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, obj_value, attr,
Object::OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT,
JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
JSReceiver::MAY_BE_STORE_FROM_KEYED,
@ -5244,8 +5249,9 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(
} else {
if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
return JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, value, attr, ALLOW_AS_CONSTANT,
JSReceiver::PERFORM_EXTENSIBILITY_CHECK, store_from_keyed);
js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
store_from_keyed);
}
}
@ -5260,8 +5266,9 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(
SLOPPY, false, DEFINE_PROPERTY);
} else {
return JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, value, attr, ALLOW_AS_CONSTANT,
JSReceiver::PERFORM_EXTENSIBILITY_CHECK, store_from_keyed);
js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
store_from_keyed);
}
}
@ -13093,8 +13100,10 @@ RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
// Get the constructor function for context extension and arguments array.
Handle<JSObject> arguments_boilerplate(
isolate->sloppy_arguments_boilerplate());
Handle<JSFunction> arguments_function(
JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
JSFunction::cast(arguments_boilerplate->map()->constructor()));
// Get the number of referencing objects.
int count;

View File

@ -922,35 +922,35 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// rax = address of new object(s) (tagged)
// rcx = argument count (untagged)
// Get the arguments map from the current native context into rdi.
Label has_mapped_parameters, instantiate;
// Get the arguments boilerplate from the current native context into rdi.
Label has_mapped_parameters, copy;
__ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
__ testp(rbx, rbx);
__ j(not_zero, &has_mapped_parameters, Label::kNear);
const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX;
const int kIndex = Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX;
__ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
__ jmp(&instantiate, Label::kNear);
__ jmp(&copy, Label::kNear);
const int kAliasedIndex = Context::ALIASED_ARGUMENTS_MAP_INDEX;
const int kAliasedIndex = Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX;
__ bind(&has_mapped_parameters);
__ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex)));
__ bind(&instantiate);
__ bind(&copy);
// rax = address of new object (tagged)
// rbx = mapped parameter count (untagged)
// rcx = argument count (untagged)
// rdi = address of arguments map (tagged)
__ movp(FieldOperand(rax, JSObject::kMapOffset), rdi);
__ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
__ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
__ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
// rdi = address of boilerplate object (tagged)
// Copy the JS object part.
for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
__ movp(rdx, FieldOperand(rdi, i));
__ movp(FieldOperand(rax, i), rdx);
}
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ movp(rdx, args.GetArgumentOperand(0));
__ AssertNotSmi(rdx);
__ movp(FieldOperand(rax, JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize),
rdx);
@ -1140,16 +1140,18 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Do the allocation of both objects in one go.
__ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
// Get the arguments map from the current native context.
// Get the arguments boilerplate from the current native context.
__ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
const int offset =
Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX);
__ movp(rdi, Operand(rdi, offset));
__ movp(FieldOperand(rax, JSObject::kMapOffset), rdi);
__ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
__ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
__ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
// Copy the JS object part.
for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
__ movp(rbx, FieldOperand(rdi, i));
__ movp(FieldOperand(rax, i), rbx);
}
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);

View File

@ -83,6 +83,7 @@ typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
// Use this to expose protected methods in i::Heap.
class TestHeap : public i::Heap {
public:
using i::Heap::AllocateArgumentsObject;
using i::Heap::AllocateByteArray;
using i::Heap::AllocateFixedArray;
using i::Heap::AllocateHeapNumber;

View File

@ -50,6 +50,7 @@ static AllocationResult AllocateAfterFailures() {
// for specific kinds.
heap->AllocateFixedArray(100).ToObjectChecked();
heap->AllocateHeapNumber(0.42).ToObjectChecked();
heap->AllocateArgumentsObject(Smi::FromInt(87), 10).ToObjectChecked();
Object* object = heap->AllocateJSObject(
*CcTest::i_isolate()->object_function()).ToObjectChecked();
heap->CopyJSObject(JSObject::cast(object)).ToObjectChecked();