Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Unified Diff: src/objects.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 94a80f7d7a2aea73db5b600c6c21fcb1d3d2218f..92e4dc4c8c9c98f03a6267e2f393dda5c4312803 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -519,7 +519,7 @@ Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
Handle<JSReceiver> receiver,
uint32_t index,
Handle<Object> value,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
Isolate* isolate = proxy->GetIsolate();
Handle<String> name = isolate->factory()->Uint32ToString(index);
return SetPropertyWithHandler(
@@ -615,29 +615,29 @@ Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
// No accessible property found.
*attributes = ABSENT;
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_GET);
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_GET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
- Object* receiver,
+ Handle<JSObject> object,
LookupResult* result,
- Name* name,
+ Handle<Name> name,
bool continue_search) {
if (result->IsProperty()) {
switch (result->type()) {
case CALLBACKS: {
// Only allow API accessors.
- Object* obj = result->GetCallbackObject();
+ Handle<Object> obj(result->GetCallbackObject(), object->GetIsolate());
if (obj->IsAccessorInfo()) {
- AccessorInfo* info = AccessorInfo::cast(obj);
+ Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj);
if (info->all_can_read()) {
return result->GetAttributes();
}
} else if (obj->IsAccessorPair()) {
- AccessorPair* pair = AccessorPair::cast(obj);
+ Handle<AccessorPair> pair = Handle<AccessorPair>::cast(obj);
if (pair->all_can_read()) {
return result->GetAttributes();
}
@@ -650,13 +650,11 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
case CONSTANT: {
if (!continue_search) break;
// Search ALL_CAN_READ accessors in prototype chain.
- LookupResult r(GetIsolate());
- result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
+ LookupResult r(object->GetIsolate());
+ result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
if (r.IsProperty()) {
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- &r,
- name,
- continue_search);
+ return GetPropertyAttributeWithFailedAccessCheck(
+ object, &r, name, continue_search);
}
break;
}
@@ -664,17 +662,15 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
case INTERCEPTOR: {
// If the object has an interceptor, try real named properties.
// No access check in GetPropertyAttributeWithInterceptor.
- LookupResult r(GetIsolate());
+ LookupResult r(object->GetIsolate());
if (continue_search) {
- result->holder()->LookupRealNamedProperty(name, &r);
+ result->holder()->LookupRealNamedProperty(*name, &r);
} else {
- result->holder()->LocalLookupRealNamedProperty(name, &r);
+ result->holder()->LocalLookupRealNamedProperty(*name, &r);
}
if (!r.IsFound()) break;
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- &r,
- name,
- continue_search);
+ return GetPropertyAttributeWithFailedAccessCheck(
+ object, &r, name, continue_search);
}
case HANDLER:
@@ -684,7 +680,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
}
}
- GetIsolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
+ object->GetIsolate()->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
return ABSENT;
}
@@ -1280,14 +1276,13 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// - the space the existing string occupies is too small for a regular
// external string.
// - the existing string is in old pointer space and the backing store of
- // the external string is not aligned. The GC cannot deal with fields
- // containing an unaligned address that points to outside of V8's heap.
+ // the external string is not aligned. The GC cannot deal with a field
+ // containing a possibly unaligned address to outside of V8's heap.
// In either case we resort to a short external string instead, omitting
// the field caching the address of the backing store. When we encounter
// short external strings in generated code, we need to bailout to runtime.
if (size < ExternalString::kSize ||
- (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) &&
- heap->old_pointer_space()->Contains(this))) {
+ heap->old_pointer_space()->Contains(this)) {
this->set_map_no_write_barrier(
is_internalized
? (is_ascii
@@ -1351,14 +1346,13 @@ bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
// - the space the existing string occupies is too small for a regular
// external string.
// - the existing string is in old pointer space and the backing store of
- // the external string is not aligned. The GC cannot deal with fields
- // containing an unaligned address that points to outside of V8's heap.
+ // the external string is not aligned. The GC cannot deal with a field
+ // containing a possibly unaligned address to outside of V8's heap.
// In either case we resort to a short external string instead, omitting
// the field caching the address of the backing store. When we encounter
// short external strings in generated code, we need to bailout to runtime.
if (size < ExternalString::kSize ||
- (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) &&
- heap->old_pointer_space()->Contains(this))) {
+ heap->old_pointer_space()->Contains(this)) {
this->set_map_no_write_barrier(
is_internalized ? heap->short_external_ascii_internalized_string_map()
: heap->short_external_ascii_string_map());
@@ -1977,31 +1971,6 @@ static Handle<Object> NewStorageFor(Isolate* isolate,
}
-void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
- Handle<Map> new_map,
- Handle<Name> name,
- Handle<Object> value,
- int field_index,
- Representation representation) {
- Isolate* isolate = object->GetIsolate();
-
- // This method is used to transition to a field. If we are transitioning to a
- // double field, allocate new storage.
- Handle<Object> storage = NewStorageFor(isolate, value, representation);
-
- if (object->map()->unused_property_fields() == 0) {
- int new_unused = new_map->unused_property_fields();
- Handle<FixedArray> properties(object->properties());
- Handle<FixedArray> values = isolate->factory()->CopySizeFixedArray(
- properties, properties->length() + new_unused + 1);
- object->set_properties(*values);
- }
-
- object->set_map(*new_map);
- object->FastPropertyAtPut(field_index, *storage);
-}
-
-
static MaybeObject* CopyAddFieldDescriptor(Map* map,
Name* name,
int index,
@@ -2066,7 +2035,16 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
Handle<Map> new_map = CopyAddFieldDescriptor(
handle(object->map()), name, index, attributes, representation, flag);
- AddFastPropertyUsingMap(object, new_map, name, value, index, representation);
+ JSObject::MigrateToMap(object, new_map);
+
+ if (representation.IsDouble()) {
+ // Nothing more to be done.
+ if (value->IsUninitialized()) return;
+ HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
+ box->set_value(value->Number());
+ } else {
+ object->FastPropertyAtPut(index, *value);
+ }
}
@@ -2110,7 +2088,7 @@ void JSObject::AddConstantProperty(Handle<JSObject> object,
Handle<Map> new_map = CopyAddConstantDescriptor(
handle(object->map()), name, constant, attributes, flag);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
}
@@ -2149,7 +2127,7 @@ Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
JSReceiver::StoreFromKeyed store_mode,
ExtensibilityCheck extensibility_check,
ValueType value_type,
@@ -2165,7 +2143,7 @@ Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
!object->map()->is_extensible()) {
- if (strict_mode == kNonStrictMode) {
+ if (strict_mode == SLOPPY) {
return value;
} else {
Handle<Object> args[1] = { name };
@@ -2199,8 +2177,7 @@ Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
AddSlowProperty(object, name, value, attributes);
}
- if (FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ if (object->map()->is_observed() &&
*name != isolate->heap()->hidden_string()) {
Handle<Object> old_value = isolate->factory()->the_hole_value();
EnqueueChangeRecord(object, "add", name, old_value);
@@ -2238,7 +2215,7 @@ Handle<Object> JSObject::SetPropertyPostInterceptor(
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
// Check local property, ignore interceptor.
LookupResult result(object->GetIsolate());
object->LocalLookupRealNamedProperty(*name, &result);
@@ -2358,16 +2335,14 @@ bool Map::InstancesNeedRewriting(Map* target,
ASSERT(target_number_of_fields >= number_of_fields);
if (target_number_of_fields != number_of_fields) return true;
- if (FLAG_track_double_fields) {
- // If smi descriptors were replaced by double descriptors, rewrite.
- DescriptorArray* old_desc = instance_descriptors();
- DescriptorArray* new_desc = target->instance_descriptors();
- int limit = NumberOfOwnDescriptors();
- for (int i = 0; i < limit; i++) {
- if (new_desc->GetDetails(i).representation().IsDouble() &&
- !old_desc->GetDetails(i).representation().IsDouble()) {
- return true;
- }
+ // If smi descriptors were replaced by double descriptors, rewrite.
+ DescriptorArray* old_desc = instance_descriptors();
+ DescriptorArray* new_desc = target->instance_descriptors();
+ int limit = NumberOfOwnDescriptors();
+ for (int i = 0; i < limit; i++) {
+ if (new_desc->GetDetails(i).representation().IsDouble() &&
+ !old_desc->GetDetails(i).representation().IsDouble()) {
+ return true;
}
}
@@ -2423,9 +2398,14 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
- int descriptors = new_map->NumberOfOwnDescriptors();
+ int old_nof = old_map->NumberOfOwnDescriptors();
+ int new_nof = new_map->NumberOfOwnDescriptors();
+
+ // This method only supports generalizing instances to at least the same
+ // number of properties.
+ ASSERT(old_nof <= new_nof);
- for (int i = 0; i < descriptors; i++) {
+ for (int i = 0; i < old_nof; i++) {
PropertyDetails details = new_descriptors->GetDetails(i);
if (details.type() != FIELD) continue;
PropertyDetails old_details = old_descriptors->GetDetails(i);
@@ -2439,22 +2419,30 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
? old_descriptors->GetValue(i)
: object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
Handle<Object> value(raw_value, isolate);
- if (FLAG_track_double_fields &&
- !old_details.representation().IsDouble() &&
+ if (!old_details.representation().IsDouble() &&
details.representation().IsDouble()) {
if (old_details.representation().IsNone()) {
value = handle(Smi::FromInt(0), isolate);
}
value = NewStorageFor(isolate, value, details.representation());
}
- ASSERT(!(FLAG_track_double_fields &&
- details.representation().IsDouble() &&
- value->IsSmi()));
+ ASSERT(!(details.representation().IsDouble() && value->IsSmi()));
int target_index = new_descriptors->GetFieldIndex(i) - inobject;
if (target_index < 0) target_index += total_size;
array->set(target_index, *value);
}
+ for (int i = old_nof; i < new_nof; i++) {
+ PropertyDetails details = new_descriptors->GetDetails(i);
+ if (details.type() != FIELD) continue;
+ if (details.representation().IsDouble()) {
+ int target_index = new_descriptors->GetFieldIndex(i) - inobject;
+ if (target_index < 0) target_index += total_size;
+ Handle<Object> box = isolate->factory()->NewHeapNumber(0);
+ array->set(target_index, *box);
+ }
+ }
+
// From here on we cannot fail and we shouldn't GC anymore.
DisallowHeapAllocation no_allocation;
@@ -2552,7 +2540,6 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
void Map::DeprecateTransitionTree() {
- if (!FLAG_track_fields) return;
if (is_deprecated()) return;
if (HasTransitionArray()) {
TransitionArray* transitions = this->transitions();
@@ -2633,6 +2620,8 @@ Map* Map::FindUpdatedMap(int verbatim,
current->instance_descriptors()->GetValue(i)) {
return NULL;
}
+ } else if (target_details.type() == CALLBACKS) {
+ return NULL;
}
}
@@ -2854,7 +2843,7 @@ Handle<Object> JSObject::SetPropertyWithInterceptor(
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
// TODO(rossberg): Support symbols in the API.
if (name->IsSymbol()) return value;
Isolate* isolate = object->GetIsolate();
@@ -2886,7 +2875,7 @@ Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
StoreFromKeyed store_mode) {
LookupResult result(object->GetIsolate());
object->LocalLookup(*name, &result, true);
@@ -2903,7 +2892,7 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
Handle<JSObject> holder,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
Isolate* isolate = object->GetIsolate();
// We should never get here to initialize a const with the hole
@@ -2962,9 +2951,7 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
return SetPropertyWithDefinedSetter(
object, Handle<JSReceiver>::cast(setter), value);
} else {
- if (strict_mode == kNonStrictMode) {
- return value;
- }
+ if (strict_mode == SLOPPY) return value;
Handle<Object> args[2] = { name, holder };
Handle<Object> error =
isolate->factory()->NewTypeError("no_setter_in_callback",
@@ -3015,7 +3002,7 @@ Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
uint32_t index,
Handle<Object> value,
bool* found,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
Isolate *isolate = object->GetIsolate();
for (Handle<Object> proto = handle(object->GetPrototype(), isolate);
!proto->IsNull();
@@ -3055,7 +3042,7 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool* done) {
Isolate* isolate = object->GetIsolate();
@@ -3073,14 +3060,12 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
*done = result.IsReadOnly();
break;
case INTERCEPTOR: {
- PropertyAttributes attr =
- result.holder()->GetPropertyAttributeWithInterceptor(
- *object, *name, true);
+ PropertyAttributes attr = GetPropertyAttributeWithInterceptor(
+ handle(result.holder()), object, name, true);
*done = !!(attr & READ_ONLY);
break;
}
case CALLBACKS: {
- if (!FLAG_es5_readonly && result.IsReadOnly()) break;
*done = true;
Handle<Object> callback_object(result.GetCallbackObject(), isolate);
return SetPropertyWithCallback(object, callback_object, name, value,
@@ -3099,9 +3084,8 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
}
// If we get here with *done true, we have encountered a read-only property.
- if (!FLAG_es5_readonly) *done = false;
if (*done) {
- if (strict_mode == kNonStrictMode) return value;
+ if (strict_mode == SLOPPY) return value;
Handle<Object> args[] = { name, object };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -3390,6 +3374,7 @@ MaybeObject* Map::AsElementsKind(ElementsKind kind) {
void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
+ DisallowHeapAllocation no_gc;
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
if (proto->IsNull()) return result->NotFound();
@@ -3469,7 +3454,7 @@ Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
Handle<Name> name,
Handle<Object> value,
bool check_prototype,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
if (check_prototype && !result->IsProperty()) {
object->LookupRealNamedPropertyInPrototypes(*name, result);
}
@@ -3525,7 +3510,7 @@ Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
}
Isolate* isolate = object->GetIsolate();
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
@@ -3536,7 +3521,7 @@ Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
StoreFromKeyed store_mode) {
if (result->IsHandler()) {
return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
@@ -3568,7 +3553,7 @@ Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
Isolate* isolate = proxy->GetIsolate();
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
@@ -3588,7 +3573,7 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool* done) {
Isolate* isolate = proxy->GetIsolate();
Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
@@ -3656,7 +3641,7 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
ASSERT(writable->IsTrue() || writable->IsFalse());
*done = writable->IsFalse();
if (!*done) return isolate->factory()->the_hole_value();
- if (strict_mode == kNonStrictMode) return value;
+ if (strict_mode == SLOPPY) return value;
Handle<Object> args[] = { name, receiver };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -3675,7 +3660,7 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
receiver, Handle<JSReceiver>::cast(setter), value);
}
- if (strict_mode == kNonStrictMode) return value;
+ if (strict_mode == SLOPPY) return value;
Handle<Object> args2[] = { name, proxy };
Handle<Object> error = isolate->factory()->NewTypeError(
"no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
@@ -3719,21 +3704,18 @@ Handle<Object> JSProxy::DeleteElementWithHandler(
}
-MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
- JSReceiver* receiver_raw,
- Name* name_raw) {
- Isolate* isolate = GetIsolate();
+PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ Handle<Name> name) {
+ Isolate* isolate = proxy->GetIsolate();
HandleScope scope(isolate);
- Handle<JSProxy> proxy(this);
- Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy.
- Handle<JSReceiver> receiver(receiver_raw);
- Handle<Object> name(name_raw, isolate);
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (name->IsSymbol()) return ABSENT;
Handle<Object> args[] = { name };
- Handle<Object> result = CallTrap(
+ Handle<Object> result = proxy->CallTrap(
"getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
if (isolate->has_pending_exception()) return NONE;
@@ -3768,6 +3750,7 @@ MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
}
if (configurable->IsFalse()) {
+ Handle<Object> handler(proxy->handler(), isolate);
Handle<String> trap = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("getPropertyDescriptor"));
Handle<Object> args[] = { handler, trap, name };
@@ -3785,15 +3768,13 @@ MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
}
-MUST_USE_RESULT PropertyAttributes JSProxy::GetElementAttributeWithHandler(
- JSReceiver* receiver_raw,
+PropertyAttributes JSProxy::GetElementAttributeWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
uint32_t index) {
- Isolate* isolate = GetIsolate();
- HandleScope scope(isolate);
- Handle<JSProxy> proxy(this);
- Handle<JSReceiver> receiver(receiver_raw);
+ Isolate* isolate = proxy->GetIsolate();
Handle<String> name = isolate->factory()->Uint32ToString(index);
- return proxy->GetPropertyAttributeWithHandler(*receiver, *name);
+ return GetPropertyAttributeWithHandler(proxy, receiver, name);
}
@@ -3869,16 +3850,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
}
map = MapAsElementsKind(map, to_kind);
}
- int total_size =
- map->NumberOfOwnDescriptors() + map->unused_property_fields();
- int out_of_object = total_size - map->inobject_properties();
- if (out_of_object != object->properties()->length()) {
- Isolate* isolate = object->GetIsolate();
- Handle<FixedArray> new_properties = isolate->factory()->CopySizeFixedArray(
- handle(object->properties()), out_of_object);
- object->set_properties(*new_properties);
- }
- object->set_map(*map);
+ JSObject::MigrateToMap(object, map);
}
@@ -3925,7 +3897,7 @@ Handle<Object> JSObject::SetPropertyUsingTransition(
// of the map. If we get a fast copy of the map, all field representations
// will be tagged since the transition is omitted.
return JSObject::AddProperty(
- object, name, value, attributes, kNonStrictMode,
+ object, name, value, attributes, SLOPPY,
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
JSReceiver::OMIT_EXTENSIBILITY_CHECK,
JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
@@ -3934,29 +3906,31 @@ Handle<Object> JSObject::SetPropertyUsingTransition(
// Keep the target CONSTANT if the same value is stored.
// TODO(verwaest): Also support keeping the placeholder
// (value->IsUninitialized) as constant.
- if (details.type() == CONSTANT &&
- descriptors->GetValue(descriptor) == *value) {
- object->set_map(*transition_map);
- return value;
- }
-
- Representation representation = details.representation();
-
- if (!value->FitsRepresentation(representation) ||
- details.type() == CONSTANT) {
+ if (!value->FitsRepresentation(details.representation()) ||
+ (details.type() == CONSTANT &&
+ descriptors->GetValue(descriptor) != *value)) {
transition_map = Map::GeneralizeRepresentation(transition_map,
descriptor, value->OptimalRepresentation(), FORCE_FIELD);
- Object* back = transition_map->GetBackPointer();
- if (back->IsMap()) {
- MigrateToMap(object, handle(Map::cast(back)));
- }
- descriptors = transition_map->instance_descriptors();
- representation = descriptors->GetDetails(descriptor).representation();
}
+ JSObject::MigrateToMap(object, transition_map);
+
+ // Reload.
+ descriptors = transition_map->instance_descriptors();
+ details = descriptors->GetDetails(descriptor);
+
+ if (details.type() != FIELD) return value;
+
int field_index = descriptors->GetFieldIndex(descriptor);
- AddFastPropertyUsingMap(
- object, transition_map, name, value, field_index, representation);
+ if (details.representation().IsDouble()) {
+ // Nothing more to be done.
+ if (value->IsUninitialized()) return value;
+ HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
+ box->set_value(value->Number());
+ } else {
+ object->FastPropertyAtPut(field_index, *value);
+ }
+
return value;
}
@@ -3976,7 +3950,7 @@ static void SetPropertyToField(LookupResult* lookup,
representation = desc->GetDetails(descriptor).representation();
}
- if (FLAG_track_double_fields && representation.IsDouble()) {
+ if (representation.IsDouble()) {
HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
lookup->GetFieldIndex().field_index()));
storage->set_value(value->Number());
@@ -4037,7 +4011,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
StoreFromKeyed store_mode) {
Isolate* isolate = object->GetIsolate();
@@ -4055,7 +4029,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
true, strict_mode);
}
@@ -4086,7 +4060,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
}
if (lookup->IsProperty() && lookup->IsReadOnly()) {
- if (strict_mode == kStrictMode) {
+ if (strict_mode == STRICT) {
Handle<Object> args[] = { name, object };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -4098,8 +4072,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup->IsDataProperty()) {
old_value = Object::GetProperty(object, name);
@@ -4190,9 +4163,9 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
- false, kNonStrictMode);
+ false, SLOPPY);
}
}
@@ -4215,14 +4188,13 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
TransitionFlag flag = lookup.IsFound()
? OMIT_TRANSITION : INSERT_TRANSITION;
// Neither properties nor transitions found.
- return AddProperty(object, name, value, attributes, kNonStrictMode,
+ return AddProperty(object, name, value, attributes, SLOPPY,
MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
PropertyAttributes old_attributes = ABSENT;
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsProperty()) {
if (lookup.IsDataProperty()) old_value =
@@ -4287,20 +4259,22 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
- JSObject* receiver,
- Name* name,
- bool continue_search) {
+ Handle<JSObject> object,
+ Handle<JSObject> receiver,
+ Handle<Name> name,
+ bool continue_search) {
// Check local property, ignore interceptor.
- LookupResult result(GetIsolate());
- LocalLookupRealNamedProperty(name, &result);
+ Isolate* isolate = object->GetIsolate();
+ LookupResult result(isolate);
+ object->LocalLookupRealNamedProperty(*name, &result);
if (result.IsFound()) return result.GetAttributes();
if (continue_search) {
// Continue searching via the prototype chain.
- Object* pt = GetPrototype();
- if (!pt->IsNull()) {
- return JSObject::cast(pt)->
- GetPropertyAttributeWithReceiver(receiver, name);
+ Handle<Object> proto(object->GetPrototype(), isolate);
+ if (!proto->IsNull()) {
+ return JSReceiver::GetPropertyAttributeWithReceiver(
+ Handle<JSObject>::cast(proto), receiver, name);
}
}
return ABSENT;
@@ -4308,31 +4282,30 @@ PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
- JSObject* receiver,
- Name* name,
- bool continue_search) {
+ Handle<JSObject> object,
+ Handle<JSObject> receiver,
+ Handle<Name> name,
+ bool continue_search) {
// TODO(rossberg): Support symbols in the API.
if (name->IsSymbol()) return ABSENT;
- Isolate* isolate = GetIsolate();
+ Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
AssertNoContextChange ncc(isolate);
- Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
- Handle<JSObject> receiver_handle(receiver);
- Handle<JSObject> holder_handle(this);
- Handle<String> name_handle(String::cast(name));
- PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
+ Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
+ PropertyCallbackArguments args(
+ isolate, interceptor->data(), *receiver, *object);
if (!interceptor->query()->IsUndefined()) {
v8::NamedPropertyQueryCallback query =
v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
LOG(isolate,
- ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
+ ApiNamedPropertyAccess("interceptor-named-has", *object, *name));
v8::Handle<v8::Integer> result =
- args.Call(query, v8::Utils::ToLocal(name_handle));
+ args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
if (!result.IsEmpty()) {
ASSERT(result->IsInt32());
return static_cast<PropertyAttributes>(result->Int32Value());
@@ -4341,44 +4314,45 @@ PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
v8::NamedPropertyGetterCallback getter =
v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
- ApiNamedPropertyAccess("interceptor-named-get-has", this, name));
+ ApiNamedPropertyAccess("interceptor-named-get-has", *object, *name));
v8::Handle<v8::Value> result =
- args.Call(getter, v8::Utils::ToLocal(name_handle));
+ args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
if (!result.IsEmpty()) return DONT_ENUM;
}
- return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle,
- *name_handle,
- continue_search);
+ return GetPropertyAttributePostInterceptor(
+ object, receiver, name, continue_search);
}
PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
- JSReceiver* receiver,
- Name* key) {
+ Handle<JSReceiver> object,
+ Handle<JSReceiver> receiver,
+ Handle<Name> key) {
uint32_t index = 0;
- if (IsJSObject() && key->AsArrayIndex(&index)) {
- return JSObject::cast(this)->GetElementAttributeWithReceiver(
- receiver, index, true);
+ if (object->IsJSObject() && key->AsArrayIndex(&index)) {
+ return JSObject::GetElementAttributeWithReceiver(
+ Handle<JSObject>::cast(object), receiver, index, true);
}
// Named property.
- LookupResult lookup(GetIsolate());
- Lookup(key, &lookup);
- return GetPropertyAttributeForResult(receiver, &lookup, key, true);
+ LookupResult lookup(object->GetIsolate());
+ object->Lookup(*key, &lookup);
+ return GetPropertyAttributeForResult(object, receiver, &lookup, key, true);
}
PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
- JSReceiver* receiver,
+ Handle<JSReceiver> object,
+ Handle<JSReceiver> receiver,
LookupResult* lookup,
- Name* name,
+ Handle<Name> name,
bool continue_search) {
// Check access rights if needed.
- if (IsAccessCheckNeeded()) {
- JSObject* this_obj = JSObject::cast(this);
- Heap* heap = GetHeap();
- if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) {
- return this_obj->GetPropertyAttributeWithFailedAccessCheck(
- receiver, lookup, name, continue_search);
+ if (object->IsAccessCheckNeeded()) {
+ Heap* heap = object->GetHeap();
+ Handle<JSObject> obj = Handle<JSObject>::cast(object);
+ if (!heap->isolate()->MayNamedAccessWrapper(obj, name, v8::ACCESS_HAS)) {
+ return JSObject::GetPropertyAttributeWithFailedAccessCheck(
+ obj, lookup, name, continue_search);
}
}
if (lookup->IsFound()) {
@@ -4389,12 +4363,15 @@ PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
case CALLBACKS:
return lookup->GetAttributes();
case HANDLER: {
- return JSProxy::cast(lookup->proxy())->GetPropertyAttributeWithHandler(
- receiver, name);
+ return JSProxy::GetPropertyAttributeWithHandler(
+ handle(lookup->proxy()), receiver, name);
}
case INTERCEPTOR:
- return lookup->holder()->GetPropertyAttributeWithInterceptor(
- JSObject::cast(receiver), name, continue_search);
+ return JSObject::GetPropertyAttributeWithInterceptor(
+ handle(lookup->holder()),
+ Handle<JSObject>::cast(receiver),
+ name,
+ continue_search);
case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
@@ -4404,67 +4381,74 @@ PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
}
-PropertyAttributes JSReceiver::GetLocalPropertyAttribute(Name* name) {
+PropertyAttributes JSReceiver::GetLocalPropertyAttribute(
+ Handle<JSReceiver> object, Handle<Name> name) {
// Check whether the name is an array index.
uint32_t index = 0;
- if (IsJSObject() && name->AsArrayIndex(&index)) {
- return GetLocalElementAttribute(index);
+ if (object->IsJSObject() && name->AsArrayIndex(&index)) {
+ return GetLocalElementAttribute(object, index);
}
// Named property.
- LookupResult lookup(GetIsolate());
- LocalLookup(name, &lookup, true);
- return GetPropertyAttributeForResult(this, &lookup, name, false);
+ LookupResult lookup(object->GetIsolate());
+ object->LocalLookup(*name, &lookup, true);
+ return GetPropertyAttributeForResult(object, object, &lookup, name, false);
}
PropertyAttributes JSObject::GetElementAttributeWithReceiver(
- JSReceiver* receiver, uint32_t index, bool continue_search) {
- Isolate* isolate = GetIsolate();
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ bool continue_search) {
+ Isolate* isolate = object->GetIsolate();
// Check access rights if needed.
- if (IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
+ if (object->IsAccessCheckNeeded()) {
+ if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
return ABSENT;
}
}
- if (IsJSGlobalProxy()) {
- Object* proto = GetPrototype();
+ if (object->IsJSGlobalProxy()) {
+ Handle<Object> proto(object->GetPrototype(), isolate);
if (proto->IsNull()) return ABSENT;
ASSERT(proto->IsJSGlobalObject());
- return JSObject::cast(proto)->GetElementAttributeWithReceiver(
- receiver, index, continue_search);
+ return JSObject::GetElementAttributeWithReceiver(
+ Handle<JSObject>::cast(proto), receiver, index, continue_search);
}
// Check for lookup interceptor except when bootstrapping.
- if (HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
- return GetElementAttributeWithInterceptor(receiver, index, continue_search);
+ if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
+ return JSObject::GetElementAttributeWithInterceptor(
+ object, receiver, index, continue_search);
}
return GetElementAttributeWithoutInterceptor(
- receiver, index, continue_search);
+ object, receiver, index, continue_search);
}
PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
- JSReceiver* receiver, uint32_t index, bool continue_search) {
- Isolate* isolate = GetIsolate();
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ bool continue_search) {
+ Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
AssertNoContextChange ncc(isolate);
- Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
- Handle<JSReceiver> hreceiver(receiver);
- Handle<JSObject> holder(this);
- PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
+ Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
+ PropertyCallbackArguments args(
+ isolate, interceptor->data(), *receiver, *object);
if (!interceptor->query()->IsUndefined()) {
v8::IndexedPropertyQueryCallback query =
v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
LOG(isolate,
- ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
+ ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
v8::Handle<v8::Integer> result = args.Call(query, index);
if (!result.IsEmpty())
return static_cast<PropertyAttributes>(result->Int32Value());
@@ -4472,37 +4456,42 @@ PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
v8::IndexedPropertyGetterCallback getter =
v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
- ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index));
+ ApiIndexedPropertyAccess(
+ "interceptor-indexed-get-has", *object, index));
v8::Handle<v8::Value> result = args.Call(getter, index);
if (!result.IsEmpty()) return NONE;
}
- return holder->GetElementAttributeWithoutInterceptor(
- *hreceiver, index, continue_search);
+ return GetElementAttributeWithoutInterceptor(
+ object, receiver, index, continue_search);
}
PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
- JSReceiver* receiver, uint32_t index, bool continue_search) {
- PropertyAttributes attr = GetElementsAccessor()->GetAttributes(
- receiver, this, index);
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ bool continue_search) {
+ PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
+ *receiver, *object, index);
if (attr != ABSENT) return attr;
// Handle [] on String objects.
- if (IsStringObjectWithCharacterAt(index)) {
+ if (object->IsStringObjectWithCharacterAt(index)) {
return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
}
if (!continue_search) return ABSENT;
- Object* pt = GetPrototype();
- if (pt->IsJSProxy()) {
+ Handle<Object> proto(object->GetPrototype(), object->GetIsolate());
+ if (proto->IsJSProxy()) {
// We need to follow the spec and simulate a call to [[GetOwnProperty]].
- return JSProxy::cast(pt)->GetElementAttributeWithHandler(receiver, index);
+ return JSProxy::GetElementAttributeWithHandler(
+ Handle<JSProxy>::cast(proto), receiver, index);
}
- if (pt->IsNull()) return ABSENT;
- return JSObject::cast(pt)->GetElementAttributeWithReceiver(
- receiver, index, true);
+ if (proto->IsNull()) return ABSENT;
+ return GetElementAttributeWithReceiver(
+ Handle<JSObject>::cast(proto), receiver, index, true);
}
@@ -4745,7 +4734,7 @@ MaybeObject* JSObject::NormalizeElements() {
FixedArrayBase* array = FixedArrayBase::cast(elements());
Map* old_map = array->map();
bool is_arguments =
- (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
+ (old_map == old_map->GetHeap()->sloppy_arguments_elements_map());
if (is_arguments) {
array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
}
@@ -4780,6 +4769,7 @@ MaybeObject* JSObject::NormalizeElements() {
MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(),
DICTIONARY_ELEMENTS);
if (!maybe->To(&new_map)) return maybe;
+ // TODO(verwaest): Replace by MigrateToMap.
set_map(new_map);
set_elements(dictionary);
}
@@ -4960,10 +4950,10 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
}
-bool JSObject::HasHiddenProperties() {
- return GetPropertyAttributePostInterceptor(this,
- GetHeap()->hidden_string(),
- false) != ABSENT;
+bool JSObject::HasHiddenProperties(Handle<JSObject> object) {
+ Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
+ return GetPropertyAttributePostInterceptor(
+ object, object, hidden, false) != ABSENT;
}
@@ -5044,7 +5034,7 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
// We can store the identity hash inline iff there is no backing store
// for hidden properties yet.
- ASSERT(object->HasHiddenProperties() != value->IsSmi());
+ ASSERT(JSObject::HasHiddenProperties(object) != value->IsSmi());
if (object->HasFastProperties()) {
// If the object has fast properties, check whether the first slot
// in the descriptor array matches the hidden string. Since the
@@ -5175,8 +5165,8 @@ Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayIndexedAccess(*object, index, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE);
+ !isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->false_value();
}
@@ -5204,7 +5194,7 @@ Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
Handle<Object> old_value;
bool should_enqueue_change_record = false;
- if (FLAG_harmony_observation && object->map()->is_observed()) {
+ if (object->map()->is_observed()) {
should_enqueue_change_record = HasLocalElement(object, index);
if (should_enqueue_change_record) {
old_value = object->GetLocalElementAccessorPair(index) != NULL
@@ -5239,8 +5229,8 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE);
+ !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5275,8 +5265,7 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsDataProperty()) {
old_value = Object::GetProperty(object, name);
@@ -5398,7 +5387,7 @@ bool JSObject::ReferencesObject(Object* obj) {
if (ReferencesObjectFromElements(elements, kind, obj)) return true;
break;
}
- case NON_STRICT_ARGUMENTS_ELEMENTS: {
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
FixedArray* parameter_map = FixedArray::cast(elements());
// Check the mapped parameters.
int length = parameter_map->length();
@@ -5420,7 +5409,7 @@ bool JSObject::ReferencesObject(Object* obj) {
// Get the constructor function for arguments array.
JSObject* arguments_boilerplate =
heap->isolate()->context()->native_context()->
- arguments_boilerplate();
+ sloppy_arguments_boilerplate();
JSFunction* arguments_function =
JSFunction::cast(arguments_boilerplate->map()->constructor());
@@ -5470,10 +5459,10 @@ Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
if (!object->map()->is_extensible()) return object;
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object,
- isolate->heap()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccessWrapper(object,
+ isolate->factory()->undefined_value(),
+ v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5509,10 +5498,10 @@ Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
Handle<Map> new_map = Map::Copy(handle(object->map()));
new_map->set_is_extensible(false);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
ASSERT(!object->map()->is_extensible());
- if (FLAG_harmony_observation && object->map()->is_observed()) {
+ if (object->map()->is_observed()) {
EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
isolate->factory()->the_hole_value());
}
@@ -5542,18 +5531,18 @@ static void FreezeDictionary(Dictionary* dictionary) {
Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
- // Freezing non-strict arguments should be handled elsewhere.
- ASSERT(!object->HasNonStrictArgumentsElements());
+ // Freezing sloppy arguments should be handled elsewhere.
+ ASSERT(!object->HasSloppyArgumentsElements());
ASSERT(!object->map()->is_observed());
if (object->map()->is_frozen()) return object;
Isolate* isolate = object->GetIsolate();
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object,
- isolate->heap()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccessWrapper(object,
+ isolate->factory()->undefined_value(),
+ v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5602,11 +5591,11 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
Handle<Map> old_map(object->map());
old_map->LookupTransition(*object, isolate->heap()->frozen_symbol(), &result);
if (result.IsTransition()) {
- Map* transition_map = result.GetTransitionTarget();
+ Handle<Map> transition_map(result.GetTransitionTarget());
ASSERT(transition_map->has_dictionary_elements());
ASSERT(transition_map->is_frozen());
ASSERT(!transition_map->is_extensible());
- object->set_map(transition_map);
+ JSObject::MigrateToMap(object, transition_map);
} else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
// Create a new descriptor array with fully-frozen properties
int num_descriptors = old_map->NumberOfOwnDescriptors();
@@ -5619,7 +5608,7 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
new_map->freeze();
new_map->set_is_extensible(false);
new_map->set_elements_kind(DICTIONARY_ELEMENTS);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
} else {
// Slow path: need to normalize properties for safety
NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
@@ -5630,7 +5619,7 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
new_map->freeze();
new_map->set_is_extensible(false);
new_map->set_elements_kind(DICTIONARY_ELEMENTS);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
// Freeze dictionary-mode properties
FreezeDictionary(object->property_dictionary());
@@ -5674,7 +5663,7 @@ void JSObject::SetObserved(Handle<JSObject> object) {
new_map = Map::Copy(handle(object->map()));
new_map->set_is_observed();
}
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
}
@@ -5795,7 +5784,7 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
ASSERT(names->get(i)->IsString());
Handle<String> key_string(String::cast(names->get(i)));
PropertyAttributes attributes =
- copy->GetLocalPropertyAttribute(*key_string);
+ JSReceiver::GetLocalPropertyAttribute(copy, key_string);
// Only deep copy fields from the object literal expression.
// In particular, don't try to copy the length attribute of
// an array.
@@ -5810,7 +5799,7 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
if (copying) {
// Creating object copy for literals. No strict mode needed.
CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
- copy, key_string, result, NONE, kNonStrictMode));
+ copy, key_string, result, NONE, SLOPPY));
}
}
}
@@ -5869,7 +5858,7 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
}
break;
}
- case NON_STRICT_ARGUMENTS_ELEMENTS:
+ case SLOPPY_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
break;
@@ -5927,9 +5916,9 @@ bool JSReceiver::IsSimpleEnum() {
JSObject* curr = JSObject::cast(o);
int enum_length = curr->map()->EnumLength();
if (enum_length == kInvalidEnumCacheSentinel) return false;
+ if (curr->IsAccessCheckNeeded()) return false;
ASSERT(!curr->HasNamedInterceptor());
ASSERT(!curr->HasIndexedInterceptor());
- ASSERT(!curr->IsAccessCheckNeeded());
if (curr->NumberOfEnumElements() > 0) return false;
if (curr != this && enum_length != 0) return false;
}
@@ -6130,7 +6119,7 @@ void JSObject::DefineElementAccessor(Handle<JSObject> object,
return;
}
break;
- case NON_STRICT_ARGUMENTS_ELEMENTS: {
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
// Ascertain whether we have read-only properties or an existing
// getter/setter pair in an arguments elements dictionary backing
// store.
@@ -6213,9 +6202,10 @@ void JSObject::DefinePropertyAccessor(Handle<JSObject> object,
}
-bool JSObject::CanSetCallback(Name* name) {
- ASSERT(!IsAccessCheckNeeded() ||
- GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
+bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) {
+ Isolate* isolate = object->GetIsolate();
+ ASSERT(!object->IsAccessCheckNeeded() ||
+ isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET));
// Check if there is an API defined callback object which prohibits
// callback overwriting in this object or its prototype chain.
@@ -6223,15 +6213,15 @@ bool JSObject::CanSetCallback(Name* name) {
// certain accessors such as window.location should not be allowed
// to be overwritten because allowing overwriting could potentially
// cause security problems.
- LookupResult callback_result(GetIsolate());
- LookupCallbackProperty(name, &callback_result);
+ LookupResult callback_result(isolate);
+ object->LookupCallbackProperty(*name, &callback_result);
if (callback_result.IsFound()) {
- Object* obj = callback_result.GetCallbackObject();
- if (obj->IsAccessorInfo()) {
- return !AccessorInfo::cast(obj)->prohibits_overwriting();
+ Object* callback_obj = callback_result.GetCallbackObject();
+ if (callback_obj->IsAccessorInfo()) {
+ return !AccessorInfo::cast(callback_obj)->prohibits_overwriting();
}
- if (obj->IsAccessorPair()) {
- return !AccessorPair::cast(obj)->prohibits_overwriting();
+ if (callback_obj->IsAccessorPair()) {
+ return !AccessorPair::cast(callback_obj)->prohibits_overwriting();
}
}
return true;
@@ -6281,7 +6271,7 @@ void JSObject::SetElementCallback(Handle<JSObject> object,
dictionary->set_requires_slow_elements();
// Update the dictionary backing store on the object.
- if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
+ if (object->elements()->map() == heap->sloppy_arguments_elements_map()) {
// Also delete any parameter alias.
//
// TODO(kmillikin): when deleting the last parameter alias we could
@@ -6338,8 +6328,8 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
Isolate* isolate = object->GetIsolate();
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
+ !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
return;
}
@@ -6363,14 +6353,13 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
// Try to flatten before operating on the string.
if (name->IsString()) String::cast(*name)->TryFlatten();
- if (!object->CanSetCallback(*name)) return;
+ if (!JSObject::CanSetCallback(object, name)) return;
uint32_t index = 0;
bool is_element = name->AsArrayIndex(&index);
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
bool preexists = false;
if (is_observed) {
@@ -6404,11 +6393,11 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
}
-static bool TryAccessorTransition(JSObject* self,
- Map* transitioned_map,
+static bool TryAccessorTransition(Handle<JSObject> self,
+ Handle<Map> transitioned_map,
int target_descriptor,
AccessorComponent component,
- Object* accessor,
+ Handle<Object> accessor,
PropertyAttributes attributes) {
DescriptorArray* descs = transitioned_map->instance_descriptors();
PropertyDetails details = descs->GetDetails(target_descriptor);
@@ -6422,8 +6411,8 @@ static bool TryAccessorTransition(JSObject* self,
PropertyAttributes target_attributes = details.attributes();
// Reuse transition if adding same accessor with same attributes.
- if (target_accessor == accessor && target_attributes == attributes) {
- self->set_map(transitioned_map);
+ if (target_accessor == *accessor && target_attributes == attributes) {
+ JSObject::MigrateToMap(self, transitioned_map);
return true;
}
@@ -6485,14 +6474,14 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
object->map()->LookupTransition(*object, *name, &result);
if (result.IsFound()) {
- Map* target = result.GetTransitionTarget();
+ Handle<Map> target(result.GetTransitionTarget());
ASSERT(target->NumberOfOwnDescriptors() ==
object->map()->NumberOfOwnDescriptors());
// This works since descriptors are sorted in order of addition.
ASSERT(object->map()->instance_descriptors()->
GetKey(descriptor_number) == *name);
- return TryAccessorTransition(*object, target, descriptor_number,
- component, *accessor, attributes);
+ return TryAccessorTransition(object, target, descriptor_number,
+ component, accessor, attributes);
}
} else {
// If not, lookup a transition.
@@ -6500,12 +6489,12 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
// If there is a transition, try to follow it.
if (result.IsFound()) {
- Map* target = result.GetTransitionTarget();
+ Handle<Map> target(result.GetTransitionTarget());
int descriptor_number = target->LastAdded();
ASSERT(target->instance_descriptors()->GetKey(descriptor_number)
->Equals(*name));
- return TryAccessorTransition(*object, target, descriptor_number,
- component, *accessor, attributes);
+ return TryAccessorTransition(object, target, descriptor_number,
+ component, accessor, attributes);
}
}
@@ -6518,7 +6507,7 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
accessors->set(component, *accessor);
Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
name, accessors, attributes);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
return true;
}
@@ -6531,8 +6520,8 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
+ !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->undefined_value();
}
@@ -6551,7 +6540,9 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
// Try to flatten before operating on the string.
if (name->IsString()) FlattenString(Handle<String>::cast(name));
- if (!object->CanSetCallback(*name)) return factory->undefined_value();
+ if (!JSObject::CanSetCallback(object, name)) {
+ return factory->undefined_value();
+ }
uint32_t index = 0;
bool is_element = name->AsArrayIndex(&index);
@@ -6581,7 +6572,7 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
case DICTIONARY_ELEMENTS:
break;
- case NON_STRICT_ARGUMENTS_ELEMENTS:
+ case SLOPPY_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
break;
}
@@ -6615,8 +6606,8 @@ Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
+ !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
@@ -6670,8 +6661,7 @@ Object* JSObject::SlowReverseLookup(Object* value) {
for (int i = 0; i < number_of_own_descriptors; i++) {
if (descs->GetType(i) == FIELD) {
Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
- if (FLAG_track_double_fields &&
- descs->GetDetails(i).representation().IsDouble()) {
+ if (descs->GetDetails(i).representation().IsDouble()) {
ASSERT(property->IsHeapNumber());
if (value->IsNumber() && property->Number() == value->Number()) {
return descs->GetKey(i);
@@ -8242,7 +8232,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) {
// Checks whether the buffer contains an identifier (no escape).
if (!name->IsString()) return false;
String* string = String::cast(name);
- if (string->length() == 0) return false;
+ if (string->length() == 0) return true;
ConsStringIteratorOp op;
StringCharacterStream stream(string, &op);
if (!cache->IsIdentifierStart(stream.GetNext())) {
@@ -8258,9 +8248,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) {
bool Name::IsCacheable(Isolate* isolate) {
- return IsSymbol() ||
- IsIdentifier(isolate->unicode_cache(), this) ||
- this == isolate->heap()->hidden_string();
+ return IsSymbol() || IsIdentifier(isolate->unicode_cache(), this);
}
@@ -9466,13 +9454,13 @@ bool Map::EquivalentToForNormalization(Map* other,
void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
- if (count_of_ptr_entries() > 0) {
- int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
- int last_ptr_offset =
- OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries() - 1);
- v->VisitPointers(
- HeapObject::RawField(this, first_ptr_offset),
- HeapObject::RawField(this, last_ptr_offset));
+ for (int i = 0; i < count_of_code_ptr_entries(); i++) {
+ int index = first_code_ptr_index() + i;
+ v->VisitCodeEntry(reinterpret_cast<Address>(RawFieldOfElementAt(index)));
+ }
+ for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
+ int index = first_heap_ptr_index() + i;
+ v->VisitPointer(RawFieldOfElementAt(index));
}
}
@@ -9640,38 +9628,42 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
const char* reason) {
if (optimized_code_map()->IsSmi()) return;
- int i;
- bool removed_entry = false;
FixedArray* code_map = FixedArray::cast(optimized_code_map());
- for (i = kEntriesStart; i < code_map->length(); i += kEntryLength) {
- ASSERT(code_map->get(i)->IsNativeContext());
- if (Code::cast(code_map->get(i + 1)) == optimized_code) {
+ int dst = kEntriesStart;
+ int length = code_map->length();
+ for (int src = kEntriesStart; src < length; src += kEntryLength) {
+ ASSERT(code_map->get(src)->IsNativeContext());
+ if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) {
+ // Evict the src entry by not copying it to the dst entry.
if (FLAG_trace_opt) {
PrintF("[evicting entry from optimizing code map (%s) for ", reason);
ShortPrint();
- PrintF("]\n");
+ BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
+ if (osr.IsNone()) {
+ PrintF("]\n");
+ } else {
+ PrintF(" (osr ast id %d)]\n", osr.ToInt());
+ }
}
- removed_entry = true;
- break;
+ } else {
+ // Keep the src entry by copying it to the dst entry.
+ if (dst != src) {
+ code_map->set(dst + kContextOffset,
+ code_map->get(src + kContextOffset));
+ code_map->set(dst + kCachedCodeOffset,
+ code_map->get(src + kCachedCodeOffset));
+ code_map->set(dst + kLiteralsOffset,
+ code_map->get(src + kLiteralsOffset));
+ code_map->set(dst + kOsrAstIdOffset,
+ code_map->get(src + kOsrAstIdOffset));
+ }
+ dst += kEntryLength;
}
}
- while (i < (code_map->length() - kEntryLength)) {
- code_map->set(i + kContextOffset,
- code_map->get(i + kContextOffset + kEntryLength));
- code_map->set(i + kCachedCodeOffset,
- code_map->get(i + kCachedCodeOffset + kEntryLength));
- code_map->set(i + kLiteralsOffset,
- code_map->get(i + kLiteralsOffset + kEntryLength));
- code_map->set(i + kOsrAstIdOffset,
- code_map->get(i + kOsrAstIdOffset + kEntryLength));
- i += kEntryLength;
- }
- if (removed_entry) {
+ if (dst != length) {
// Always trim even when array is cleared because of heap verifier.
- RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, kEntryLength);
- if (code_map->length() == kEntriesStart) {
- ClearOptimizedCodeMap();
- }
+ RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, length - dst);
+ if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap();
}
}
@@ -9799,7 +9791,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
// different prototype.
Handle<Map> new_map = Map::Copy(handle(function->map()));
- function->set_map(*new_map);
+ JSObject::MigrateToMap(function, new_map);
new_map->set_constructor(*value);
new_map->set_non_instance_prototype(true);
Isolate* isolate = new_map->GetIsolate();
@@ -9816,15 +9808,15 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
void JSFunction::RemovePrototype() {
Context* native_context = context()->native_context();
- Map* no_prototype_map = shared()->is_classic_mode()
- ? native_context->function_without_prototype_map()
- : native_context->strict_mode_function_without_prototype_map();
+ Map* no_prototype_map = shared()->strict_mode() == SLOPPY
+ ? native_context->sloppy_function_without_prototype_map()
+ : native_context->strict_function_without_prototype_map();
if (map() == no_prototype_map) return;
- ASSERT(map() == (shared()->is_classic_mode()
- ? native_context->function_map()
- : native_context->strict_mode_function_map()));
+ ASSERT(map() == (shared()->strict_mode() == SLOPPY
+ ? native_context->sloppy_function_map()
+ : native_context->strict_function_map()));
set_map(no_prototype_map);
set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
@@ -10642,26 +10634,24 @@ void Code::ClearInlineCaches(Code::Kind* kind) {
Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
if (target->is_inline_cache_stub()) {
if (kind == NULL || *kind == target->kind()) {
- IC::Clear(this->GetIsolate(), info->pc());
+ IC::Clear(this->GetIsolate(), info->pc(),
+ info->host()->constant_pool());
}
}
}
}
-void Code::ClearTypeFeedbackInfo(Heap* heap) {
- if (kind() != FUNCTION) return;
- Object* raw_info = type_feedback_info();
- if (raw_info->IsTypeFeedbackInfo()) {
- FixedArray* feedback_vector =
- TypeFeedbackInfo::cast(raw_info)->feedback_vector();
- for (int i = 0; i < feedback_vector->length(); i++) {
- Object* obj = feedback_vector->get(i);
- if (!obj->IsAllocationSite()) {
- // TODO(mvstanton): Can't I avoid a write barrier for this sentinel?
- feedback_vector->set(i,
- TypeFeedbackInfo::RawUninitializedSentinel(heap));
- }
+void SharedFunctionInfo::ClearTypeFeedbackInfo(Heap* heap) {
+ FixedArray* vector = feedback_vector();
+ for (int i = 0; i < vector->length(); i++) {
+ Object* obj = vector->get(i);
+ if (!obj->IsAllocationSite()) {
+ // The assert verifies we can skip the write barrier.
+ ASSERT(heap->uninitialized_symbol() ==
+ TypeFeedbackInfo::RawUninitializedSentinel(heap));
+ vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap),
+ SKIP_WRITE_BARRIER);
}
}
}
@@ -11086,9 +11076,7 @@ void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
switch (kind) {
case STORE_IC:
case KEYED_STORE_IC:
- if (extra == kStrictMode) {
- name = "STRICT";
- }
+ if (extra == STRICT) name = "STRICT";
break;
default:
break;
@@ -11255,7 +11243,7 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
accessor->CopyElements(this, new_elements, elements_kind);
if (maybe_obj->IsFailure()) return maybe_obj;
- if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
+ if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
Map* new_map = map();
if (new_elements_kind != elements_kind) {
MaybeObject* maybe =
@@ -11327,7 +11315,7 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
accessor->CopyElements(this, elems, elements_kind);
if (maybe_obj->IsFailure()) return maybe_obj;
}
- if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
+ if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
ValidateElements();
set_map_and_elements(new_map, elems);
} else {
@@ -11369,7 +11357,8 @@ static bool GetOldValue(Isolate* isolate,
uint32_t index,
List<Handle<Object> >* old_values,
List<uint32_t>* indices) {
- PropertyAttributes attributes = object->GetLocalElementAttribute(index);
+ PropertyAttributes attributes =
+ JSReceiver::GetLocalElementAttribute(object, index);
ASSERT(attributes != ABSENT);
if (attributes == DONT_DELETE) return false;
old_values->Add(object->GetLocalElementAccessorPair(index) == NULL
@@ -11432,7 +11421,7 @@ static void EndPerformSplice(Handle<JSArray> object) {
MaybeObject* JSArray::SetElementsLength(Object* len) {
// We should never end in here with a pixel or external array.
ASSERT(AllowsSetElementsLength());
- if (!(FLAG_harmony_observation && map()->is_observed()))
+ if (!map()->is_observed())
return GetElementsAccessor()->SetLength(this, len);
Isolate* isolate = GetIsolate();
@@ -11498,12 +11487,12 @@ MaybeObject* JSArray::SetElementsLength(Object* len) {
if (delete_count > 0) {
for (int i = indices.length() - 1; i >= 0; i--) {
JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
- kNonStrictMode);
+ SLOPPY);
}
SetProperty(deleted, isolate->factory()->length_string(),
isolate->factory()->NewNumberFromUint(delete_count),
- NONE, kNonStrictMode);
+ NONE, SLOPPY);
}
EnqueueSpliceRecord(self, index, deleted, add_count);
@@ -11876,7 +11865,7 @@ Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
new_map->set_prototype(*value);
}
ASSERT(new_map->prototype() == *value);
- real_receiver->set_map(*new_map);
+ JSObject::MigrateToMap(real_receiver, new_map);
if (!dictionary_elements_in_chain &&
new_map->DictionaryElementsInPrototypeChainOnly()) {
@@ -11942,7 +11931,7 @@ Handle<Object> JSObject::SetElementWithInterceptor(
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode) {
Isolate* isolate = object->GetIsolate();
@@ -12030,7 +12019,7 @@ Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
Handle<JSObject> holder,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
Isolate* isolate = object->GetIsolate();
// We should never get here to initialize a const with the hole
@@ -12069,9 +12058,7 @@ Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
return SetPropertyWithDefinedSetter(
object, Handle<JSReceiver>::cast(setter), value);
} else {
- if (strict_mode == kNonStrictMode) {
- return value;
- }
+ if (strict_mode == SLOPPY) return value;
Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
Handle<Object> args[2] = { key, holder };
Handle<Object> error = isolate->factory()->NewTypeError(
@@ -12093,7 +12080,7 @@ bool JSObject::HasFastArgumentsElements() {
Heap* heap = GetHeap();
if (!elements()->IsFixedArray()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
- if (elements->map() != heap->non_strict_arguments_elements_map()) {
+ if (elements->map() != heap->sloppy_arguments_elements_map()) {
return false;
}
FixedArray* arguments = FixedArray::cast(elements->get(1));
@@ -12105,7 +12092,7 @@ bool JSObject::HasDictionaryArgumentsElements() {
Heap* heap = GetHeap();
if (!elements()->IsFixedArray()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
- if (elements->map() != heap->non_strict_arguments_elements_map()) {
+ if (elements->map() != heap->sloppy_arguments_elements_map()) {
return false;
}
FixedArray* arguments = FixedArray::cast(elements->get(1));
@@ -12119,7 +12106,7 @@ bool JSObject::HasDictionaryArgumentsElements() {
Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype) {
ASSERT(object->HasFastSmiOrObjectElements() ||
object->HasFastArgumentsElements());
@@ -12137,7 +12124,7 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
if (backing_store->map() ==
- isolate->heap()->non_strict_arguments_elements_map()) {
+ isolate->heap()->sloppy_arguments_elements_map()) {
backing_store = handle(FixedArray::cast(backing_store->get(1)));
} else {
backing_store = EnsureWritableFastElements(object);
@@ -12217,7 +12204,7 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
UpdateAllocationSite(object, kind);
Handle<Map> new_map = GetElementsTransitionMap(object, kind);
- object->set_map(*new_map);
+ JSObject::MigrateToMap(object, new_map);
ASSERT(IsFastObjectElementsKind(object->GetElementsKind()));
}
// Increase backing store capacity if that's been decided previously.
@@ -12248,7 +12235,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode) {
ASSERT(object->HasDictionaryElements() ||
@@ -12258,7 +12245,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
// Insert element in the dictionary.
Handle<FixedArray> elements(FixedArray::cast(object->elements()));
bool is_arguments =
- (elements->map() == isolate->heap()->non_strict_arguments_elements_map());
+ (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
Handle<SeededNumberDictionary> dictionary(is_arguments
? SeededNumberDictionary::cast(elements->get(1))
: SeededNumberDictionary::cast(*elements));
@@ -12280,7 +12267,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
attributes, NORMAL, details.dictionary_index());
dictionary->DetailsAtPut(entry, details);
} else if (details.IsReadOnly() && !element->IsTheHole()) {
- if (strict_mode == kNonStrictMode) {
+ if (strict_mode == SLOPPY) {
return isolate->factory()->undefined_value();
} else {
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
@@ -12318,7 +12305,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
// When we set the is_extensible flag to false we always force the
// element into dictionary mode (and force them to stay there).
if (!object->map()->is_extensible()) {
- if (strict_mode == kNonStrictMode) {
+ if (strict_mode == SLOPPY) {
return isolate->factory()->undefined_value();
} else {
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
@@ -12391,7 +12378,7 @@ Handle<Object> JSObject::SetFastDoubleElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype) {
ASSERT(object->HasFastDoubleElements());
@@ -12489,7 +12476,7 @@ Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
if (object->IsJSProxy()) {
return JSProxy::SetElementWithHandler(
Handle<JSProxy>::cast(object), object, index, value, strict_mode);
@@ -12502,7 +12489,7 @@ Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
- StrictModeFlag strict_mode) {
+ StrictMode strict_mode) {
ASSERT(!object->HasExternalArrayElements());
return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
}
@@ -12512,7 +12499,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode) {
Isolate* isolate = object->GetIsolate();
@@ -12529,8 +12516,8 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
+ if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
@@ -12563,7 +12550,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
dictionary->set_requires_slow_elements();
}
- if (!(FLAG_harmony_observation && object->map()->is_observed())) {
+ if (!object->map()->is_observed()) {
return object->HasIndexedInterceptor()
? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
check_prototype,
@@ -12574,7 +12561,8 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
set_mode);
}
- PropertyAttributes old_attributes = object->GetLocalElementAttribute(index);
+ PropertyAttributes old_attributes =
+ JSReceiver::GetLocalElementAttribute(object, index);
Handle<Object> old_value = isolate->factory()->the_hole_value();
Handle<Object> old_length_handle;
Handle<Object> new_length_handle;
@@ -12600,7 +12588,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
Handle<String> name = isolate->factory()->Uint32ToString(index);
- PropertyAttributes new_attributes = object->GetLocalElementAttribute(index);
+ PropertyAttributes new_attributes = GetLocalElementAttribute(object, index);
if (old_attributes == ABSENT) {
if (object->IsJSArray() &&
!old_length_handle->SameValue(
@@ -12645,7 +12633,7 @@ Handle<Object> JSObject::SetElementWithoutInterceptor(
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode) {
ASSERT(object->HasDictionaryElements() ||
@@ -12693,7 +12681,7 @@ Handle<Object> JSObject::SetElementWithoutInterceptor(
return SetDictionaryElement(object, index, value, attributes, strict_mode,
check_prototype,
set_mode);
- case NON_STRICT_ARGUMENTS_ELEMENTS: {
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
uint32_t length = parameter_map->length();
Handle<Object> probe = index < length - 2 ?
@@ -12906,6 +12894,7 @@ MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind);
Map* new_map;
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ // TODO(verwaest): Replace by MigrateToMap.
set_map(new_map);
if (FLAG_trace_elements_transitions) {
FixedArrayBase* elms = FixedArrayBase::cast(elements());
@@ -13052,7 +13041,7 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
FixedArray* backing_store = NULL;
switch (GetElementsKind()) {
- case NON_STRICT_ARGUMENTS_ELEMENTS:
+ case SLOPPY_ARGUMENTS_ELEMENTS:
backing_store_base =
FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
backing_store = FixedArray::cast(backing_store_base);
@@ -13120,6 +13109,21 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
}
+bool JSObject::WouldConvertToSlowElements(Handle<Object> key) {
+ uint32_t index;
+ if (HasFastElements() && key->ToArrayIndex(&index)) {
+ Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
+ uint32_t capacity = static_cast<uint32_t>(backing_store->length());
+ if (index >= capacity) {
+ if ((index - capacity) >= kMaxGap) return true;
+ uint32_t new_capacity = NewElementsCapacity(index + 1);
+ return ShouldConvertToSlowElements(new_capacity);
+ }
+ }
+ return false;
+}
+
+
bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <=
kMaxUncheckedFastElementsLength);
@@ -13149,11 +13153,11 @@ bool JSObject::ShouldConvertToFastElements() {
if (IsAccessCheckNeeded()) return false;
// Observed objects may not go to fast mode because they rely on map checks,
// and for fast element accesses we sometimes check element kinds only.
- if (FLAG_harmony_observation && map()->is_observed()) return false;
+ if (map()->is_observed()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
SeededNumberDictionary* dictionary = NULL;
- if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
+ if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) {
dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
dictionary = SeededNumberDictionary::cast(elements);
@@ -13343,8 +13347,8 @@ bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
return false;
}
}
@@ -13357,11 +13361,11 @@ bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
Isolate* isolate = object->GetIsolate();
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
+ if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
return false;
}
}
@@ -13374,8 +13378,8 @@ bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
return HasRealElementProperty(Handle<JSObject>::cast(proto), index);
}
- return object->GetElementAttributeWithoutInterceptor(
- *object, index, false) != ABSENT;
+ return GetElementAttributeWithoutInterceptor(
+ object, object, index, false) != ABSENT;
}
@@ -13385,8 +13389,8 @@ bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
return false;
}
}
@@ -13633,7 +13637,7 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
break;
}
- case NON_STRICT_ARGUMENTS_ELEMENTS: {
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
FixedArray* parameter_map = FixedArray::cast(elements());
int mapped_length = parameter_map->length() - 2;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
@@ -13731,11 +13735,11 @@ class StringSharedKey : public HashTableKey {
public:
StringSharedKey(String* source,
SharedFunctionInfo* shared,
- LanguageMode language_mode,
+ StrictMode strict_mode,
int scope_position)
: source_(source),
shared_(shared),
- language_mode_(language_mode),
+ strict_mode_(strict_mode),
scope_position_(scope_position) { }
bool IsMatch(Object* other) {
@@ -13743,12 +13747,10 @@ class StringSharedKey : public HashTableKey {
FixedArray* other_array = FixedArray::cast(other);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
if (shared != shared_) return false;
- int language_unchecked = Smi::cast(other_array->get(2))->value();
- ASSERT(language_unchecked == CLASSIC_MODE ||
- language_unchecked == STRICT_MODE ||
- language_unchecked == EXTENDED_MODE);
- LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
- if (language_mode != language_mode_) return false;
+ int strict_unchecked = Smi::cast(other_array->get(2))->value();
+ ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
+ StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
+ if (strict_mode != strict_mode_) return false;
int scope_position = Smi::cast(other_array->get(3))->value();
if (scope_position != scope_position_) return false;
String* source = String::cast(other_array->get(1));
@@ -13757,7 +13759,7 @@ class StringSharedKey : public HashTableKey {
static uint32_t StringSharedHashHelper(String* source,
SharedFunctionInfo* shared,
- LanguageMode language_mode,
+ StrictMode strict_mode,
int scope_position) {
uint32_t hash = source->Hash();
if (shared->HasSourceCode()) {
@@ -13768,8 +13770,7 @@ class StringSharedKey : public HashTableKey {
// collection.
Script* script = Script::cast(shared->script());
hash ^= String::cast(script->source())->Hash();
- if (language_mode == STRICT_MODE) hash ^= 0x8000;
- if (language_mode == EXTENDED_MODE) hash ^= 0x0080;
+ if (strict_mode == STRICT) hash ^= 0x8000;
hash += scope_position;
}
return hash;
@@ -13777,21 +13778,19 @@ class StringSharedKey : public HashTableKey {
uint32_t Hash() {
return StringSharedHashHelper(
- source_, shared_, language_mode_, scope_position_);
+ source_, shared_, strict_mode_, scope_position_);
}
uint32_t HashForObject(Object* obj) {
FixedArray* other_array = FixedArray::cast(obj);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
String* source = String::cast(other_array->get(1));
- int language_unchecked = Smi::cast(other_array->get(2))->value();
- ASSERT(language_unchecked == CLASSIC_MODE ||
- language_unchecked == STRICT_MODE ||
- language_unchecked == EXTENDED_MODE);
- LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
+ int strict_unchecked = Smi::cast(other_array->get(2))->value();
+ ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
+ StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
int scope_position = Smi::cast(other_array->get(3))->value();
return StringSharedHashHelper(
- source, shared, language_mode, scope_position);
+ source, shared, strict_mode, scope_position);
}
MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
@@ -13802,7 +13801,7 @@ class StringSharedKey : public HashTableKey {
FixedArray* other_array = FixedArray::cast(obj);
other_array->set(0, shared_);
other_array->set(1, source_);
- other_array->set(2, Smi::FromInt(language_mode_));
+ other_array->set(2, Smi::FromInt(strict_mode_));
other_array->set(3, Smi::FromInt(scope_position_));
return other_array;
}
@@ -13810,7 +13809,7 @@ class StringSharedKey : public HashTableKey {
private:
String* source_;
SharedFunctionInfo* shared_;
- LanguageMode language_mode_;
+ StrictMode strict_mode_;
int scope_position_;
};
@@ -14446,8 +14445,11 @@ MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
uint32_t limit) {
Isolate* isolate = object->GetIsolate();
+ if (object->HasSloppyArgumentsElements() ||
+ object->map()->is_observed()) {
+ return handle(Smi::FromInt(-1), isolate);
+ }
- ASSERT(!object->map()->is_observed());
if (object->HasDictionaryElements()) {
// Convert to fast elements containing only the existing properties.
// Ordering is irrelevant, since we are going to sort anyway.
@@ -15003,22 +15005,11 @@ MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) {
}
-// The key for the script compilation cache is dependent on the mode flags,
-// because they change the global language mode and thus binding behaviour.
-// If flags change at some point, we must ensure that we do not hit the cache
-// for code compiled with different settings.
-static LanguageMode CurrentGlobalLanguageMode() {
- return FLAG_use_strict
- ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE)
- : CLASSIC_MODE;
-}
-
-
Object* CompilationCacheTable::Lookup(String* src, Context* context) {
SharedFunctionInfo* shared = context->closure()->shared();
StringSharedKey key(src,
shared,
- CurrentGlobalLanguageMode(),
+ FLAG_use_strict ? STRICT : SLOPPY,
RelocInfo::kNoPosition);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
@@ -15028,11 +15019,11 @@ Object* CompilationCacheTable::Lookup(String* src, Context* context) {
Object* CompilationCacheTable::LookupEval(String* src,
Context* context,
- LanguageMode language_mode,
+ StrictMode strict_mode,
int scope_position) {
StringSharedKey key(src,
context->closure()->shared(),
- language_mode,
+ strict_mode,
scope_position);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
@@ -15055,7 +15046,7 @@ MaybeObject* CompilationCacheTable::Put(String* src,
SharedFunctionInfo* shared = context->closure()->shared();
StringSharedKey key(src,
shared,
- CurrentGlobalLanguageMode(),
+ FLAG_use_strict ? STRICT : SLOPPY,
RelocInfo::kNoPosition);
CompilationCacheTable* cache;
MaybeObject* maybe_cache = EnsureCapacity(1, &key);
@@ -15079,7 +15070,7 @@ MaybeObject* CompilationCacheTable::PutEval(String* src,
int scope_position) {
StringSharedKey key(src,
context->closure()->shared(),
- value->language_mode(),
+ value->strict_mode(),
scope_position);
Object* obj;
{ MaybeObject* maybe_obj = EnsureCapacity(1, &key);
@@ -15522,7 +15513,7 @@ int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
template<typename Shape, typename Key>
int Dictionary<Shape, Key>::NumberOfEnumElements() {
return NumberOfElementsFilterAttributes(
- static_cast<PropertyAttributes>(DONT_ENUM));
+ static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
}
@@ -15550,45 +15541,38 @@ void Dictionary<Shape, Key>::CopyKeysTo(
}
-FixedArray* NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
+struct EnumIndexComparator {
+ explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { }
+ bool operator() (Smi* a, Smi* b) {
+ PropertyDetails da(dict->DetailsAt(a->value()));
+ PropertyDetails db(dict->DetailsAt(b->value()));
+ return da.dictionary_index() < db.dictionary_index();
+ }
+ NameDictionary* dict;
+};
+
+
+void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
int length = storage->length();
- ASSERT(length >= NumberOfEnumElements());
- Heap* heap = GetHeap();
- Object* undefined_value = heap->undefined_value();
int capacity = Capacity();
int properties = 0;
-
- // Fill in the enumeration array by assigning enumerable keys at their
- // enumeration index. This will leave holes in the array if there are keys
- // that are deleted or not enumerable.
for (int i = 0; i < capacity; i++) {
Object* k = KeyAt(i);
if (IsKey(k) && !k->IsSymbol()) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted() || details.IsDontEnum()) continue;
+ storage->set(properties, Smi::FromInt(i));
properties++;
- storage->set(details.dictionary_index() - 1, k);
if (properties == length) break;
}
}
-
- // There are holes in the enumeration array if less properties were assigned
- // than the length of the array. If so, crunch all the existing properties
- // together by shifting them to the left (maintaining the enumeration order),
- // and trimming of the right side of the array.
- if (properties < length) {
- if (properties == 0) return heap->empty_fixed_array();
- properties = 0;
- for (int i = 0; i < length; ++i) {
- Object* value = storage->get(i);
- if (value != undefined_value) {
- storage->set(properties, value);
- ++properties;
- }
- }
- RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties);
+ EnumIndexComparator cmp(this);
+ Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
+ std::sort(start, start + length, cmp);
+ for (int i = 0; i < length; i++) {
+ int index = Smi::cast(storage->get(i))->value();
+ storage->set(i, KeyAt(index));
}
- return storage;
}
@@ -15724,7 +15708,6 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor(
// instance descriptor.
MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
if (!maybe_key->To(&key)) return maybe_key;
- if (key->Equals(heap->empty_string())) return this;
}
PropertyDetails details = DetailsAt(i);
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698