__ 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));
// 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;
// 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));
// 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.
// 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);
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()));
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);
-
- ASSERT(map->inobject_properties() > Heap::kArgumentsCalleeIndex);
- ASSERT(map->inobject_properties() > Heap::kArgumentsLengthIndex);
- ASSERT(!map->is_dictionary_map());
- ASSERT(IsFastObjectElementsKind(map->elements_kind()));
- }
+ 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);
+
+ 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);
- { // --- 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);
+#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
}
- { // --- strict mode arguments 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 boilerplate
const PropertyAttributes attributes =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
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);
}
// Copy constructor from the sloppy arguments boilerplate.
map->set_constructor(
- native_context()->sloppy_arguments_map()->constructor());
+ native_context()->sloppy_arguments_boilerplate()->map()->constructor());
+
+ // Allocate the arguments boilerplate object.
+ Handle<JSObject> result = factory->NewJSObjectFromMap(map);
+ native_context()->set_strict_arguments_boilerplate(*result);
+
+#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);
- native_context()->set_strict_arguments_map(*map);
+ ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
- ASSERT(map->inobject_properties() > Heap::kArgumentsLengthIndex);
- ASSERT(!map->is_dictionary_map());
- ASSERT(IsFastObjectElementsKind(map->elements_kind()));
+ // Check the state of the object.
+ ASSERT(result->HasFastProperties());
+ ASSERT(result->HasFastObjectElements());
+#endif
}
{ // --- context extension
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) {
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;
}
} 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() &&
// 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
// 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,
// Total number of slots.
NATIVE_CONTEXT_SLOTS,
+
FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
};
#include "src/factory.h"
-#include "src/allocation-site-scopes.h"
#include "src/conversions.h"
#include "src/isolate-inl.h"
#include "src/macro-assembler.h"
}
-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);
}
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.
}
+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) {
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,
__ 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.
__ 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(©, 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(©);
// 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),
// 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);
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
+ ValueType value_type,
TransitionFlag flag) {
ASSERT(!object->IsJSGlobalProxy());
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),
StrictMode strict_mode,
JSReceiver::StoreFromKeyed store_mode,
ExtensibilityCheck extensibility_check,
+ ValueType value_type,
StoreMode mode,
TransitionFlag transition_flag) {
ASSERT(!object->IsJSGlobalProxy());
if (object->HasFastProperties()) {
AddFastProperty(object, name, value, attributes, store_mode,
- transition_flag);
+ value_type, transition_flag);
}
if (!object->HasFastProperties()) {
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.
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
+ ValueType value_type,
StoreMode store_mode) {
#ifdef DEBUG
uint32_t index;
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();
}
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
+ ValueType value_type,
StoreMode mode,
ExtensibilityCheck extensibility_check,
StoreFromKeyed store_from_keyed,
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() ||
? 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();
}
}
- 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;
}
// 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);
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);
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;
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()) {
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,
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
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(
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);
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
+ ValueType value_type,
TransitionFlag flag);
// Add a property to a slow-case object.
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);
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).
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
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);
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,
} 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);
}
}
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);
}
}
// 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;
// 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(©, 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(©);
// 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);
// 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);
// 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;
// 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();