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

Unified Diff: src/objects.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 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
===================================================================
--- src/objects.cc (revision 10404)
+++ src/objects.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -246,8 +246,8 @@
}
// __defineGetter__ callback
- if (structure->IsFixedArray()) {
- Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* getter = AccessorPair::cast(structure)->getter();
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
@@ -485,6 +485,16 @@
}
+Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyDetails details) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetNormalizedProperty(*key, *value, details),
+ Object);
+}
+
+
MaybeObject* JSObject::SetNormalizedProperty(String* name,
Object* value,
PropertyDetails details) {
@@ -1961,6 +1971,17 @@
}
+Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetProperty(*key, *value, attributes, strict_mode),
+ Object);
+}
+
+
MaybeObject* JSReceiver::SetProperty(String* name,
Object* value,
PropertyAttributes attributes,
@@ -2018,8 +2039,8 @@
return *value_handle;
}
- if (structure->IsFixedArray()) {
- Object* setter = FixedArray::cast(structure)->get(kSetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* setter = AccessorPair::cast(structure)->setter();
if (setter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value);
@@ -2107,9 +2128,10 @@
if (!JSObject::cast(pt)->HasDictionaryElements()) {
continue;
}
- NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
+ SeededNumberDictionary* dictionary =
+ JSObject::cast(pt)->element_dictionary();
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
*found = true;
@@ -2342,7 +2364,9 @@
if (details.type() == ELEMENTS_TRANSITION) {
return descriptors->GetValue(index);
} else {
- *safe_to_add_transition = false;
+ if (safe_to_add_transition != NULL) {
+ *safe_to_add_transition = false;
+ }
}
}
return NULL;
@@ -3024,6 +3048,18 @@
// Note that this method cannot be used to set the prototype of a function
// because ConvertDescriptorToField() which is called in "case CALLBACKS:"
// doesn't handle function prototypes correctly.
+Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ CALL_HEAP_FUNCTION(
+ object->GetIsolate(),
+ object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes),
+ Object);
+}
+
+
MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
String* name,
Object* value,
@@ -3314,6 +3350,15 @@
}
+void JSObject::NormalizeProperties(Handle<JSObject> object,
+ PropertyNormalizationMode mode,
+ int expected_additional_properties) {
+ CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
+ object->NormalizeProperties(
+ mode, expected_additional_properties));
+}
+
+
MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
int expected_additional_properties) {
if (!HasFastProperties()) return this;
@@ -3436,6 +3481,14 @@
}
+void JSObject::TransformToFastProperties(Handle<JSObject> object,
+ int unused_property_fields) {
+ CALL_HEAP_FUNCTION_VOID(
+ object->GetIsolate(),
+ object->TransformToFastProperties(unused_property_fields));
+}
+
+
MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
if (HasFastProperties()) return this;
ASSERT(!IsGlobalObject());
@@ -3444,6 +3497,14 @@
}
+Handle<SeededNumberDictionary> JSObject::NormalizeElements(
+ Handle<JSObject> object) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->NormalizeElements(),
+ SeededNumberDictionary);
+}
+
+
MaybeObject* JSObject::NormalizeElements() {
ASSERT(!HasExternalArrayElements());
@@ -3468,11 +3529,11 @@
int old_capacity = 0;
int used_elements = 0;
GetElementsCapacityAndUsage(&old_capacity, &used_elements);
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ Object* object;
- MaybeObject* maybe = NumberDictionary::Allocate(used_elements);
+ MaybeObject* maybe = SeededNumberDictionary::Allocate(used_elements);
if (!maybe->ToObject(&object)) return maybe;
- dictionary = NumberDictionary::cast(object);
+ dictionary = SeededNumberDictionary::cast(object);
}
// Copy the elements to the new backing store.
@@ -3503,7 +3564,7 @@
MaybeObject* maybe_result =
dictionary->AddNumberEntry(i, value, details);
if (!maybe_result->ToObject(&result)) return maybe_result;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
}
@@ -3560,6 +3621,14 @@
}
+int JSObject::GetIdentityHash(Handle<JSObject> obj) {
+ CALL_AND_RETRY(obj->GetIsolate(),
+ obj->GetIdentityHash(ALLOW_CREATION),
+ return Smi::cast(__object__)->value(),
+ return 0);
+}
+
+
MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) {
Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol());
if (stored_value->IsSmi()) return stored_value;
@@ -3612,6 +3681,15 @@
}
+Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj,
+ Handle<String> key,
+ Handle<Object> value) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->SetHiddenProperty(*key, *value),
+ Object);
+}
+
+
MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
if (IsJSGlobalProxy()) {
// For a proxy, use the prototype as target object.
@@ -3839,6 +3917,14 @@
}
+Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj,
+ uint32_t index) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->DeleteElement(index, JSObject::NORMAL_DELETION),
+ Object);
+}
+
+
MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
Isolate* isolate = GetIsolate();
// Check access rights if needed.
@@ -3867,22 +3953,14 @@
}
-MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
- if (IsJSProxy()) {
- return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
- }
- return JSObject::cast(this)->DeleteProperty(name, mode);
+Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj,
+ Handle<String> prop) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
+ Object);
}
-MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
- if (IsJSProxy()) {
- return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
- }
- return JSObject::cast(this)->DeleteElement(index, mode);
-}
-
-
MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
Isolate* isolate = GetIsolate();
// ECMA-262, 3rd, 8.6.2.5
@@ -3940,6 +4018,22 @@
}
+MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
+ if (IsJSProxy()) {
+ return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
+ }
+ return JSObject::cast(this)->DeleteElement(index, mode);
+}
+
+
+MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
+ if (IsJSProxy()) {
+ return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
+ }
+ return JSObject::cast(this)->DeleteProperty(name, mode);
+}
+
+
bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,
Object* object) {
@@ -3954,7 +4048,8 @@
if (!element->IsTheHole() && element == object) return true;
}
} else {
- Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
+ Object* key =
+ SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
if (!key->IsUndefined()) return true;
}
return false;
@@ -4066,6 +4161,11 @@
}
+Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object);
+}
+
+
MaybeObject* JSObject::PreventExtensions() {
Isolate* isolate = GetIsolate();
if (IsAccessCheckNeeded() &&
@@ -4095,9 +4195,9 @@
}
// If there are fast elements we normalize.
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ MaybeObject* maybe = NormalizeElements();
- if (!maybe->To<NumberDictionary>(&dictionary)) return maybe;
+ if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe;
}
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
// Make sure that we never go back to fast case.
@@ -4257,21 +4357,21 @@
// Search for a getter or setter in an elements dictionary and update its
-// attributes. Returns either undefined if the element is non-deletable, or
-// the getter/setter pair (fixed array) if there is an existing one, or the
-// hole value if the element does not exist or is a normal non-getter/setter
-// data element.
-static Object* UpdateGetterSetterInDictionary(NumberDictionary* dictionary,
- uint32_t index,
- PropertyAttributes attributes,
- Heap* heap) {
+// attributes. Returns either undefined if the element is non-deletable, or the
+// getter/setter pair if there is an existing one, or the hole value if the
+// element does not exist or is a normal non-getter/setter data element.
+static Object* UpdateGetterSetterInDictionary(
+ SeededNumberDictionary* dictionary,
+ uint32_t index,
+ PropertyAttributes attributes,
+ Heap* heap) {
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* result = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
// TODO(mstarzinger): We should check for details.IsDontDelete() here once
// we only call into the runtime once to set both getter and setter.
- if (details.type() == CALLBACKS && result->IsFixedArray()) {
+ if (details.type() == CALLBACKS && result->IsAccessorPair()) {
if (details.attributes() != attributes) {
dictionary->DetailsAtPut(entry,
PropertyDetails(attributes, CALLBACKS, index));
@@ -4338,7 +4438,8 @@
if (probe == NULL || probe->IsTheHole()) {
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
probe = UpdateGetterSetterInDictionary(dictionary,
index,
attributes,
@@ -4359,7 +4460,7 @@
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
// Need to preserve old getters/setters.
- if (obj->IsFixedArray()) {
+ if (obj->IsAccessorPair()) {
// Use set to update attributes.
return SetPropertyCallback(name, obj, attributes);
}
@@ -4367,16 +4468,15 @@
}
}
- // Allocate the fixed array to hold getter and setter.
- Object* structure;
- { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED);
- if (!maybe_structure->ToObject(&structure)) return maybe_structure;
+ AccessorPair* accessors;
+ { MaybeObject* maybe_accessors = heap->AllocateAccessorPair();
+ if (!maybe_accessors->To<AccessorPair>(&accessors)) return maybe_accessors;
}
if (is_element) {
- return SetElementCallback(index, structure, attributes);
+ return SetElementCallback(index, accessors, attributes);
} else {
- return SetPropertyCallback(name, structure, attributes);
+ return SetPropertyCallback(name, accessors, attributes);
}
}
@@ -4411,11 +4511,11 @@
PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
// Normalize elements to make this operation simple.
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ Object* result;
MaybeObject* maybe = NormalizeElements();
if (!maybe->ToObject(&result)) return maybe;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
@@ -4423,7 +4523,7 @@
{ Object* result;
MaybeObject* maybe = dictionary->Set(index, structure, details);
if (!maybe->ToObject(&result)) return maybe;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
dictionary->set_requires_slow_elements();
@@ -4512,12 +4612,16 @@
fun, attributes);
}
- Object* array;
- { MaybeObject* maybe_array = DefineGetterSetter(name, attributes);
- if (!maybe_array->ToObject(&array)) return maybe_array;
+ Object* accessors;
+ { MaybeObject* maybe_accessors = DefineGetterSetter(name, attributes);
+ if (!maybe_accessors->To<Object>(&accessors)) return maybe_accessors;
}
- if (array->IsUndefined()) return array;
- FixedArray::cast(array)->set(is_getter ? 0 : 1, fun);
+ if (accessors->IsUndefined()) return accessors;
+ if (is_getter) {
+ AccessorPair::cast(accessors)->set_getter(fun);
+ } else {
+ AccessorPair::cast(accessors)->set_setter(fun);
+ }
return this;
}
@@ -4621,11 +4725,6 @@
}
// Make the lookup and include prototypes.
- // Introducing constants below makes static constants usage purely static
- // and avoids linker errors in debug build using gcc.
- const int getter_index = kGetterIndex;
- const int setter_index = kSetterIndex;
- int accessor_index = is_getter ? getter_index : setter_index;
uint32_t index = 0;
if (name->AsArrayIndex(&index)) {
for (Object* obj = this;
@@ -4633,14 +4732,15 @@
obj = JSObject::cast(obj)->GetPrototype()) {
JSObject* js_object = JSObject::cast(obj);
if (js_object->HasDictionaryElements()) {
- NumberDictionary* dictionary = js_object->element_dictionary();
+ SeededNumberDictionary* dictionary = js_object->element_dictionary();
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
- if (element->IsFixedArray()) {
- return FixedArray::cast(element)->get(accessor_index);
+ if (element->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(element);
+ return is_getter ? accessors->getter() : accessors->setter();
}
}
}
@@ -4656,8 +4756,9 @@
if (result.IsReadOnly()) return heap->undefined_value();
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
- if (obj->IsFixedArray()) {
- return FixedArray::cast(obj)->get(accessor_index);
+ if (obj->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(obj);
+ return is_getter ? accessors->getter() : accessors->setter();
}
}
}
@@ -6833,14 +6934,14 @@
if (StringShape(this).IsSequentialAscii()) {
field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(),
len,
- GetHeap()->StringHashSeed());
+ GetHeap()->HashSeed());
} else if (StringShape(this).IsSequentialTwoByte()) {
field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(),
len,
- GetHeap()->StringHashSeed());
+ GetHeap()->HashSeed());
} else {
StringInputBuffer buffer(this);
- field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed());
+ field = ComputeHashField(&buffer, len, GetHeap()->HashSeed());
}
// Store the hash code in the object.
@@ -8171,7 +8272,7 @@
}
-static void CopySlowElementsToFast(NumberDictionary* source,
+static void CopySlowElementsToFast(SeededNumberDictionary* source,
FixedArray* destination,
WriteBarrierMode mode) {
int destination_length = destination->length();
@@ -8237,7 +8338,7 @@
case DICTIONARY_ELEMENTS: {
AssertNoAllocation no_gc;
WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
- CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw),
+ CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw),
new_elements,
mode);
set_map_and_elements(new_map, new_elements);
@@ -8251,7 +8352,7 @@
FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- CopySlowElementsToFast(NumberDictionary::cast(arguments),
+ CopySlowElementsToFast(SeededNumberDictionary::cast(arguments),
new_elements,
mode);
} else {
@@ -8347,7 +8448,7 @@
break;
}
case DICTIONARY_ELEMENTS: {
- elems->Initialize(NumberDictionary::cast(old_elements));
+ elems->Initialize(SeededNumberDictionary::cast(old_elements));
break;
}
default:
@@ -8607,7 +8708,7 @@
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound) {
+ != SeededNumberDictionary::kNotFound) {
return true;
}
break;
@@ -8745,7 +8846,7 @@
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index) !=
- NumberDictionary::kNotFound) {
+ SeededNumberDictionary::kNotFound) {
return DICTIONARY_ELEMENT;
}
break;
@@ -8762,8 +8863,9 @@
// If not aliased, check the arguments.
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
- if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) {
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
+ if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) {
return DICTIONARY_ELEMENT;
}
} else {
@@ -8792,8 +8894,8 @@
return true;
}
} else {
- if (NumberDictionary::cast(elements)->FindEntry(index) !=
- NumberDictionary::kNotFound) {
+ if (SeededNumberDictionary::cast(elements)->FindEntry(index) !=
+ SeededNumberDictionary::kNotFound) {
return true;
}
}
@@ -8860,7 +8962,7 @@
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound) {
+ != SeededNumberDictionary::kNotFound) {
return true;
}
break;
@@ -8964,8 +9066,8 @@
}
// __defineGetter__ callback
- if (structure->IsFixedArray()) {
- Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* getter = AccessorPair::cast(structure)->getter();
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
@@ -9021,8 +9123,8 @@
return *value_handle;
}
- if (structure->IsFixedArray()) {
- Handle<Object> setter(FixedArray::cast(structure)->get(kSetterIndex));
+ if (structure->IsAccessorPair()) {
+ Handle<Object> setter(AccessorPair::cast(structure)->setter());
if (setter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value);
@@ -9183,15 +9285,15 @@
FixedArray* elements = FixedArray::cast(this->elements());
bool is_arguments =
(elements->map() == heap->non_strict_arguments_elements_map());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (is_arguments) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
@@ -9236,13 +9338,13 @@
FixedArrayBase* new_dictionary;
MaybeObject* maybe = dictionary->AtNumberPut(index, value);
if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe;
- if (dictionary != NumberDictionary::cast(new_dictionary)) {
+ if (dictionary != SeededNumberDictionary::cast(new_dictionary)) {
if (is_arguments) {
elements->set(1, new_dictionary);
} else {
set_elements(new_dictionary);
}
- dictionary = NumberDictionary::cast(new_dictionary);
+ dictionary = SeededNumberDictionary::cast(new_dictionary);
}
}
@@ -9388,6 +9490,35 @@
}
+Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode) {
+ ASSERT(!object->HasExternalArrayElements());
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetElement(index, *value, strict_mode, false),
+ Object);
+}
+
+
+Handle<Object> JSObject::SetElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode) {
+ if (object->HasExternalArrayElements()) {
+ if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) {
+ bool has_exception;
+ Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ if (has_exception) return Handle<Object>();
+ value = number;
+ }
+ }
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetElement(index, *value, strict_mode, true),
+ Object);
+}
+
+
MaybeObject* JSObject::SetElement(uint32_t index,
Object* value,
StrictModeFlag strict_mode,
@@ -9510,6 +9641,14 @@
}
+Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object,
+ ElementsKind to_kind) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->TransitionElementsKind(to_kind),
+ Object);
+}
+
+
MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind(
ElementsKind to_kind) {
ElementsKind from_kind = map()->elements_kind();
@@ -9653,7 +9792,8 @@
FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
backing_store = FixedArray::cast(backing_store_base);
if (backing_store->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(backing_store);
*capacity = dictionary->Capacity();
*used = dictionary->NumberOfElements();
break;
@@ -9668,8 +9808,8 @@
}
break;
case DICTIONARY_ELEMENTS: {
- NumberDictionary* dictionary =
- NumberDictionary::cast(FixedArray::cast(elements()));
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(FixedArray::cast(elements()));
*capacity = dictionary->Capacity();
*used = dictionary->NumberOfElements();
break;
@@ -9714,8 +9854,8 @@
int old_capacity = 0;
int used_elements = 0;
GetElementsCapacityAndUsage(&old_capacity, &used_elements);
- int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) *
- NumberDictionary::kEntrySize;
+ int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
+ SeededNumberDictionary::kEntrySize;
return 3 * dictionary_size <= new_capacity;
}
@@ -9729,11 +9869,11 @@
if (IsAccessCheckNeeded()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
// If an element has been added at a very high index in the elements
// dictionary, we cannot go back to fast case.
@@ -9748,7 +9888,7 @@
array_size = dictionary->max_number_key();
}
uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
- NumberDictionary::kEntrySize;
+ SeededNumberDictionary::kEntrySize;
return 2 * dictionary_size >= array_size;
}
@@ -9758,7 +9898,8 @@
*has_smi_only_elements = false;
if (FLAG_unbox_double_arrays) {
ASSERT(HasDictionaryElements());
- NumberDictionary* dictionary = NumberDictionary::cast(elements());
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(elements());
bool found_double = false;
for (int i = 0; i < dictionary->Capacity(); i++) {
Object* key = dictionary->KeyAt(i);
@@ -9978,7 +10119,7 @@
}
case DICTIONARY_ELEMENTS: {
return element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound;
+ != SeededNumberDictionary::kNotFound;
}
case NON_STRICT_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
@@ -10247,7 +10388,7 @@
if (storage != NULL) {
element_dictionary()->CopyKeysTo(storage,
filter,
- NumberDictionary::SORTED);
+ SeededNumberDictionary::SORTED);
}
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
break;
@@ -10259,9 +10400,11 @@
if (arguments->IsDictionary()) {
// Copy the keys from arguments first, because Dictionary::CopyKeysTo
// will insert in storage starting at index 0.
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
if (storage != NULL) {
- dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED);
+ dictionary->CopyKeysTo(
+ storage, filter, SeededNumberDictionary::UNSORTED);
}
counter += dictionary->NumberOfElementsFilterAttributes(filter);
for (int i = 0; i < mapped_length; ++i) {
@@ -10585,7 +10728,7 @@
uint32_t Hash() {
ASSERT(length_ >= 0);
ASSERT(from_ + length_ <= string_->length());
- StringHasher hasher(length_, string_->GetHeap()->StringHashSeed());
+ StringHasher hasher(length_, string_->GetHeap()->HashSeed());
// Very long strings have a trivial hash that doesn't inspect the
// string contents.
@@ -10794,7 +10937,7 @@
uint32_t from_index = EntryToIndex(i);
Object* k = get(from_index);
if (IsKey(k)) {
- uint32_t hash = Shape::HashForObject(key, k);
+ uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
uint32_t insertion_index =
EntryToIndex(new_table->FindInsertionEntry(hash));
for (int j = 0; j < Shape::kEntrySize; j++) {
@@ -10892,38 +11035,46 @@
template class Dictionary<StringDictionaryShape, String*>;
-template class Dictionary<NumberDictionaryShape, uint32_t>;
+template class Dictionary<SeededNumberDictionaryShape, uint32_t>;
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
- int);
+template class Dictionary<UnseededNumberDictionaryShape, uint32_t>;
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ Allocate(int at_least_space_for);
+
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ Allocate(int at_least_space_for);
+
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
int);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut(
uint32_t, Object*);
-template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup(
- Object*);
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ AtPut(uint32_t, Object*);
+template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ SlowReverseLookup(Object* value);
+
template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup(
Object*);
-template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo(
+template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo(
FixedArray*,
PropertyAttributes,
- Dictionary<NumberDictionaryShape, uint32_t>::SortMode);
+ Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode);
template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty(
int, JSObject::DeleteMode);
-template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty(
- int, JSObject::DeleteMode);
+template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ DeleteProperty(int, JSObject::DeleteMode);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink(
String*);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink(
uint32_t);
template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
@@ -10942,32 +11093,41 @@
Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
template int
-Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes(
- PropertyAttributes);
+Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ NumberOfElementsFilterAttributes(PropertyAttributes);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add(
uint32_t, Object*, PropertyDetails);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add(
+ uint32_t, Object*, PropertyDetails);
+
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
EnsureCapacity(int, uint32_t);
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ EnsureCapacity(int, uint32_t);
+
template MaybeObject* Dictionary<StringDictionaryShape, String*>::
EnsureCapacity(int, String*);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry(
- uint32_t, Object*, PropertyDetails, uint32_t);
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
+
template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry(
String*, Object*, PropertyDetails, uint32_t);
template
-int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements();
+int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
template
int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
template
-int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
+int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
// Collates undefined and unexisting elements below limit from position
@@ -10977,7 +11137,7 @@
// Must stay in dictionary mode, either because of requires_slow_elements,
// or because we are not going to sort (and therefore compact) all of the
// elements.
- NumberDictionary* dict = element_dictionary();
+ SeededNumberDictionary* dict = element_dictionary();
HeapNumber* result_double = NULL;
if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
// Allocate space for result before we start mutating the object.
@@ -10990,10 +11150,10 @@
Object* obj;
{ MaybeObject* maybe_obj =
- NumberDictionary::Allocate(dict->NumberOfElements());
+ SeededNumberDictionary::Allocate(dict->NumberOfElements());
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- NumberDictionary* new_dict = NumberDictionary::cast(obj);
+ SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj);
AssertNoAllocation no_alloc;
@@ -11077,7 +11237,7 @@
if (HasDictionaryElements()) {
// Convert to fast elements containing only the existing properties.
// Ordering is irrelevant, since we are going to sort anyway.
- NumberDictionary* dict = element_dictionary();
+ SeededNumberDictionary* dict = element_dictionary();
if (IsJSArray() || dict->requires_slow_elements() ||
dict->max_number_key() >= limit) {
return PrepareSlowElementsForSort(limit);
@@ -11444,7 +11604,7 @@
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
- if ((hash & String::kHashBitMask) == 0) hash = 27;
+ if ((hash & String::kHashBitMask) == 0) hash = String::kZeroHash;
#ifdef DEBUG
StringHasher hasher(2, seed);
hasher.AddCharacter(c1);
@@ -11503,7 +11663,7 @@
bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
uint32_t c2,
String** symbol) {
- TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed());
+ TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed());
int entry = FindEntry(&key);
if (entry == kNotFound) {
return false;
@@ -11518,14 +11678,14 @@
MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str,
Object** s) {
- Utf8SymbolKey key(str, GetHeap()->StringHashSeed());
+ Utf8SymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
Object** s) {
- AsciiSymbolKey key(str, GetHeap()->StringHashSeed());
+ AsciiSymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
@@ -11534,14 +11694,14 @@
int from,
int length,
Object** s) {
- SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed());
+ SubStringAsciiSymbolKey key(str, from, length, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
Object** s) {
- TwoByteSymbolKey key(str, GetHeap()->StringHashSeed());
+ TwoByteSymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
@@ -11880,8 +12040,9 @@
if (!maybe_k->ToObject(&k)) return maybe_k;
}
PropertyDetails details = PropertyDetails(NONE, NORMAL);
- return Dictionary<Shape, Key>::cast(obj)->
- AddEntry(key, value, details, Shape::Hash(key));
+
+ return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
+ Dictionary<Shape, Key>::Hash(key));
}
@@ -11896,8 +12057,9 @@
{ MaybeObject* maybe_obj = EnsureCapacity(1, key);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- return Dictionary<Shape, Key>::cast(obj)->
- AddEntry(key, value, details, Shape::Hash(key));
+
+ return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
+ Dictionary<Shape, Key>::Hash(key));
}
@@ -11930,7 +12092,7 @@
}
-void NumberDictionary::UpdateMaxNumberKey(uint32_t key) {
+void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
// If the dictionary requires slow elements an element has already
// been added at a high index.
if (requires_slow_elements()) return;
@@ -11949,31 +12111,65 @@
}
-MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key,
- Object* value,
- PropertyDetails details) {
+MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key,
+ Object* value,
+ PropertyDetails details) {
UpdateMaxNumberKey(key);
SLOW_ASSERT(this->FindEntry(key) == kNotFound);
return Add(key, value, details);
}
-MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) {
+MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key,
+ Object* value) {
+ SLOW_ASSERT(this->FindEntry(key) == kNotFound);
+ return Add(key, value, PropertyDetails(NONE, NORMAL));
+}
+
+
+MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) {
UpdateMaxNumberKey(key);
return AtPut(key, value);
}
-MaybeObject* NumberDictionary::Set(uint32_t key,
- Object* value,
- PropertyDetails details) {
+MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key,
+ Object* value) {
+ return AtPut(key, value);
+}
+
+
+Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyDetails details) {
+ CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
+ dictionary->Set(index, *value, details),
+ SeededNumberDictionary);
+}
+
+
+Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value) {
+ CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
+ dictionary->Set(index, *value),
+ UnseededNumberDictionary);
+}
+
+
+MaybeObject* SeededNumberDictionary::Set(uint32_t key,
+ Object* value,
+ PropertyDetails details) {
int entry = FindEntry(key);
if (entry == kNotFound) return AddNumberEntry(key, value, details);
// Preserve enumeration index.
details = PropertyDetails(details.attributes(),
details.type(),
DetailsAt(entry).index());
- MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key);
+ MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key);
Object* object_key;
if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
SetEntry(entry, object_key, value, details);
@@ -11981,7 +12177,19 @@
}
+MaybeObject* UnseededNumberDictionary::Set(uint32_t key,
+ Object* value) {
+ int entry = FindEntry(key);
+ if (entry == kNotFound) return AddNumberEntry(key, value);
+ MaybeObject* maybe_object_key = UnseededNumberDictionaryShape::AsObject(key);
+ Object* object_key;
+ if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
+ SetEntry(entry, object_key, value);
+ return this;
+}
+
+
template<typename Shape, typename Key>
int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
PropertyAttributes filter) {
« 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