Merge AddFastElement and AddFastDoubleElement
BUG=v8:4137 LOG=n Review URL: https://codereview.chromium.org/1198343004 Cr-Commit-Position: refs/heads/master@{#29227}
This commit is contained in:
parent
47421760f4
commit
359142c330
@ -11,6 +11,7 @@
|
|||||||
#include "src/bootstrapper.h"
|
#include "src/bootstrapper.h"
|
||||||
#include "src/builtins.h"
|
#include "src/builtins.h"
|
||||||
#include "src/cpu-profiler.h"
|
#include "src/cpu-profiler.h"
|
||||||
|
#include "src/elements.h"
|
||||||
#include "src/gdb-jit.h"
|
#include "src/gdb-jit.h"
|
||||||
#include "src/heap/mark-compact.h"
|
#include "src/heap/mark-compact.h"
|
||||||
#include "src/heap-profiler.h"
|
#include "src/heap-profiler.h"
|
||||||
|
@ -138,6 +138,9 @@ class ElementsAccessor {
|
|||||||
static void InitializeOncePerProcess();
|
static void InitializeOncePerProcess();
|
||||||
static void TearDown();
|
static void TearDown();
|
||||||
|
|
||||||
|
virtual void Set(FixedArrayBase* backing_store, uint32_t key,
|
||||||
|
Object* value) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class SloppyArgumentsElementsAccessor;
|
friend class SloppyArgumentsElementsAccessor;
|
||||||
friend class LookupIterator;
|
friend class LookupIterator;
|
||||||
@ -164,9 +167,6 @@ class ElementsAccessor {
|
|||||||
uint32_t index) = 0;
|
uint32_t index) = 0;
|
||||||
virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t key) = 0;
|
virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t key) = 0;
|
||||||
|
|
||||||
virtual void Set(FixedArrayBase* backing_store, uint32_t key,
|
|
||||||
Object* value) = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ElementsAccessor** elements_accessors_;
|
static ElementsAccessor** elements_accessors_;
|
||||||
const char* name_;
|
const char* name_;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "src/base/bits.h"
|
#include "src/base/bits.h"
|
||||||
#include "src/double.h"
|
#include "src/double.h"
|
||||||
|
#include "src/elements.h"
|
||||||
#include "src/factory.h"
|
#include "src/factory.h"
|
||||||
#include "src/hydrogen-infer-representation.h"
|
#include "src/hydrogen-infer-representation.h"
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "src/lookup.h"
|
#include "src/lookup.h"
|
||||||
|
|
||||||
|
#include "src/elements.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "src/base/bits.h"
|
#include "src/base/bits.h"
|
||||||
#include "src/contexts.h"
|
#include "src/contexts.h"
|
||||||
#include "src/conversions-inl.h"
|
#include "src/conversions-inl.h"
|
||||||
#include "src/elements.h"
|
|
||||||
#include "src/factory.h"
|
#include "src/factory.h"
|
||||||
#include "src/field-index-inl.h"
|
#include "src/field-index-inl.h"
|
||||||
#include "src/heap/heap-inl.h"
|
#include "src/heap/heap-inl.h"
|
||||||
@ -1605,16 +1604,6 @@ FixedArrayBase* JSObject::elements() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSObject::ValidateElements(Handle<JSObject> object) {
|
|
||||||
#ifdef ENABLE_SLOW_DCHECKS
|
|
||||||
if (FLAG_enable_slow_asserts) {
|
|
||||||
ElementsAccessor* accessor = object->GetElementsAccessor();
|
|
||||||
accessor->Validate(object);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AllocationSite::Initialize() {
|
void AllocationSite::Initialize() {
|
||||||
set_transition_info(Smi::FromInt(0));
|
set_transition_info(Smi::FromInt(0));
|
||||||
SetElementsKind(GetInitialFastElementsKind());
|
SetElementsKind(GetInitialFastElementsKind());
|
||||||
@ -6227,11 +6216,6 @@ ElementsKind JSObject::GetElementsKind() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ElementsAccessor* JSObject::GetElementsAccessor() {
|
|
||||||
return ElementsAccessor::ForKind(GetElementsKind());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool JSObject::HasFastObjectElements() {
|
bool JSObject::HasFastObjectElements() {
|
||||||
return IsFastObjectElementsKind(GetElementsKind());
|
return IsFastObjectElementsKind(GetElementsKind());
|
||||||
}
|
}
|
||||||
|
356
src/objects.cc
356
src/objects.cc
@ -12351,98 +12351,18 @@ bool JSObject::HasDictionaryArgumentsElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSObject::AddFastElement(Handle<JSObject> object, uint32_t index,
|
ElementsAccessor* JSObject::GetElementsAccessor() {
|
||||||
Handle<Object> value) {
|
return ElementsAccessor::ForKind(GetElementsKind());
|
||||||
DCHECK(object->HasFastSmiOrObjectElements() ||
|
}
|
||||||
object->HasFastArgumentsElements());
|
|
||||||
|
|
||||||
Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
|
|
||||||
if (object->HasSloppyArgumentsElements()) {
|
void JSObject::ValidateElements(Handle<JSObject> object) {
|
||||||
backing_store = handle(FixedArray::cast(backing_store->get(1)));
|
#ifdef ENABLE_SLOW_DCHECKS
|
||||||
} else {
|
if (FLAG_enable_slow_asserts) {
|
||||||
backing_store = EnsureWritableFastElements(object);
|
ElementsAccessor* accessor = object->GetElementsAccessor();
|
||||||
|
accessor->Validate(object);
|
||||||
}
|
}
|
||||||
uint32_t capacity = static_cast<uint32_t>(backing_store->length());
|
#endif
|
||||||
|
|
||||||
// Check if the length property of this object needs to be updated.
|
|
||||||
uint32_t array_length = 0;
|
|
||||||
bool must_update_array_length = false;
|
|
||||||
bool introduces_holes = true;
|
|
||||||
if (object->IsJSArray()) {
|
|
||||||
CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length));
|
|
||||||
introduces_holes = index > array_length;
|
|
||||||
if (index >= array_length) {
|
|
||||||
must_update_array_length = true;
|
|
||||||
array_length = index + 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
introduces_holes = index >= capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t new_capacity = capacity;
|
|
||||||
// Check if the capacity of the backing store needs to be increased, or if
|
|
||||||
// a transition to slow elements is necessary.
|
|
||||||
if (index >= capacity) {
|
|
||||||
bool convert_to_slow = true;
|
|
||||||
if ((index - capacity) < kMaxGap) {
|
|
||||||
new_capacity = NewElementsCapacity(index + 1);
|
|
||||||
DCHECK_LT(index, new_capacity);
|
|
||||||
convert_to_slow = object->ShouldConvertToSlowElements(new_capacity);
|
|
||||||
}
|
|
||||||
if (convert_to_slow) {
|
|
||||||
NormalizeElements(object);
|
|
||||||
AddDictionaryElement(object, index, value, NONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->HasFastSmiElements() && !value->IsSmi()) {
|
|
||||||
// Convert to fast double elements if appropriate.
|
|
||||||
if (value->IsNumber()) {
|
|
||||||
ElementsKind to_kind =
|
|
||||||
introduces_holes ? FAST_HOLEY_DOUBLE_ELEMENTS : FAST_DOUBLE_ELEMENTS;
|
|
||||||
ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind);
|
|
||||||
accessor->GrowCapacityAndConvert(object, new_capacity);
|
|
||||||
AddFastDoubleElement(object, index, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change elements kind from Smi-only to generic FAST if necessary.
|
|
||||||
ElementsKind kind = introduces_holes || object->HasFastHoleyElements()
|
|
||||||
? FAST_HOLEY_ELEMENTS
|
|
||||||
: FAST_ELEMENTS;
|
|
||||||
|
|
||||||
UpdateAllocationSite(object, kind);
|
|
||||||
Handle<Map> new_map = GetElementsTransitionMap(object, kind);
|
|
||||||
JSObject::MigrateToMap(object, new_map);
|
|
||||||
DCHECK(IsFastObjectElementsKind(object->GetElementsKind()));
|
|
||||||
} else if (introduces_holes && !object->HasFastHoleyElements()) {
|
|
||||||
// If the array is growing, and it's not growth by a single element at the
|
|
||||||
// end, make sure that the ElementsKind is HOLEY.
|
|
||||||
ElementsKind transitioned_kind =
|
|
||||||
GetHoleyElementsKind(object->GetElementsKind());
|
|
||||||
TransitionElementsKind(object, transitioned_kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increase backing store capacity if that's been decided previously.
|
|
||||||
if (capacity != new_capacity) {
|
|
||||||
DCHECK(!object->HasFastDoubleElements());
|
|
||||||
ElementsAccessor* accessor =
|
|
||||||
value->IsSmi() || object->HasSloppyArgumentsElements()
|
|
||||||
? object->GetElementsAccessor()
|
|
||||||
: ElementsAccessor::ForKind(FAST_ELEMENTS);
|
|
||||||
accessor->GrowCapacityAndConvert(object, new_capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (must_update_array_length) {
|
|
||||||
Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedArray* elements = FixedArray::cast(object->elements());
|
|
||||||
if (object->HasSloppyArgumentsElements()) {
|
|
||||||
elements = FixedArray::cast(elements->get(1));
|
|
||||||
}
|
|
||||||
elements->set(index, *value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -12482,30 +12402,6 @@ void JSObject::SetDictionaryArgumentsElement(Handle<JSObject> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSObject::AddSloppyArgumentsElement(Handle<JSObject> object,
|
|
||||||
uint32_t index, Handle<Object> value,
|
|
||||||
PropertyAttributes attributes) {
|
|
||||||
DCHECK(object->HasSloppyArgumentsElements());
|
|
||||||
|
|
||||||
// TODO(verwaest): Handle with the elements accessor.
|
|
||||||
FixedArray* parameter_map = FixedArray::cast(object->elements());
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
uint32_t length = parameter_map->length();
|
|
||||||
if (index < length - 2) {
|
|
||||||
Object* probe = parameter_map->get(index + 2);
|
|
||||||
DCHECK(probe->IsTheHole());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (parameter_map->get(1)->IsDictionary()) {
|
|
||||||
AddDictionaryElement(object, index, value, attributes);
|
|
||||||
} else {
|
|
||||||
AddFastElement(object, index, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index,
|
void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index,
|
||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes) {
|
PropertyAttributes attributes) {
|
||||||
@ -12597,8 +12493,7 @@ void JSObject::AddDictionaryElement(Handle<JSObject> object, uint32_t index,
|
|||||||
if (object->ShouldConvertToFastElements()) {
|
if (object->ShouldConvertToFastElements()) {
|
||||||
uint32_t new_length = 0;
|
uint32_t new_length = 0;
|
||||||
if (object->IsJSArray()) {
|
if (object->IsJSArray()) {
|
||||||
CHECK(
|
CHECK(JSArray::cast(*object)->length()->ToArrayLength(&new_length));
|
||||||
Handle<JSArray>::cast(object)->length()->ToArrayLength(&new_length));
|
|
||||||
} else {
|
} else {
|
||||||
new_length = dictionary->max_number_key() + 1;
|
new_length = dictionary->max_number_key() + 1;
|
||||||
}
|
}
|
||||||
@ -12616,78 +12511,6 @@ void JSObject::AddDictionaryElement(Handle<JSObject> object, uint32_t index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSObject::AddFastDoubleElement(Handle<JSObject> object, uint32_t index,
|
|
||||||
Handle<Object> value) {
|
|
||||||
DCHECK(object->HasFastDoubleElements());
|
|
||||||
|
|
||||||
Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements()));
|
|
||||||
uint32_t capacity = static_cast<uint32_t>(base_elms->length());
|
|
||||||
|
|
||||||
// Check if the length property of this object needs to be updated.
|
|
||||||
uint32_t array_length = 0;
|
|
||||||
bool must_update_array_length = false;
|
|
||||||
bool introduces_holes = true;
|
|
||||||
if (object->IsJSArray()) {
|
|
||||||
// In case of JSArray, the length does not equal the capacity.
|
|
||||||
CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length));
|
|
||||||
introduces_holes = index > array_length;
|
|
||||||
if (index >= array_length) {
|
|
||||||
must_update_array_length = true;
|
|
||||||
array_length = index + 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
introduces_holes = index >= capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t new_capacity = capacity;
|
|
||||||
// Check if the capacity of the backing store needs to be increased, or if
|
|
||||||
// a transition to slow elements is necessary.
|
|
||||||
if (index >= capacity) {
|
|
||||||
bool convert_to_slow = true;
|
|
||||||
if ((index - capacity) < kMaxGap) {
|
|
||||||
new_capacity = NewElementsCapacity(index + 1);
|
|
||||||
DCHECK_LT(index, new_capacity);
|
|
||||||
convert_to_slow = object->ShouldConvertToSlowElements(new_capacity);
|
|
||||||
}
|
|
||||||
if (convert_to_slow) {
|
|
||||||
NormalizeElements(object);
|
|
||||||
AddDictionaryElement(object, index, value, NONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the value object is not a heap number, switch to fast elements and try
|
|
||||||
// again.
|
|
||||||
if (!value->IsNumber()) {
|
|
||||||
ElementsKind to_kind =
|
|
||||||
introduces_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
|
||||||
ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind);
|
|
||||||
accessor->GrowCapacityAndConvert(object, new_capacity);
|
|
||||||
return AddFastElement(object, index, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the array is growing, and it's not growth by a single element at the
|
|
||||||
// end, make sure that the ElementsKind is HOLEY.
|
|
||||||
if (introduces_holes && !object->HasFastHoleyElements()) {
|
|
||||||
ElementsKind transitioned_kind =
|
|
||||||
GetHoleyElementsKind(object->GetElementsKind());
|
|
||||||
TransitionElementsKind(object, transitioned_kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increase backing store capacity if that's been decided previously.
|
|
||||||
if (capacity != new_capacity) {
|
|
||||||
ElementsAccessor* accessor = object->GetElementsAccessor();
|
|
||||||
accessor->GrowCapacityAndConvert(object, new_capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (must_update_array_length) {
|
|
||||||
Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedDoubleArray::cast(object->elements())->set(index, value->Number());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
|
MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
|
||||||
uint32_t index, Handle<Object> value,
|
uint32_t index, Handle<Object> value,
|
||||||
@ -12698,66 +12521,109 @@ MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void AddFastElement(Handle<JSObject> object, uint32_t index,
|
||||||
|
Handle<Object> value, ElementsKind from_kind,
|
||||||
|
uint32_t capacity, uint32_t new_capacity) {
|
||||||
|
// Check if the length property of this object needs to be updated.
|
||||||
|
uint32_t array_length = 0;
|
||||||
|
bool introduces_holes = true;
|
||||||
|
if (object->IsJSArray()) {
|
||||||
|
CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length));
|
||||||
|
introduces_holes = index > array_length;
|
||||||
|
} else {
|
||||||
|
introduces_holes = index >= capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementsKind to_kind = value->OptimalElementsKind();
|
||||||
|
if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind);
|
||||||
|
to_kind = IsMoreGeneralElementsKindTransition(from_kind, to_kind) ? to_kind
|
||||||
|
: from_kind;
|
||||||
|
if (introduces_holes) to_kind = GetHoleyElementsKind(to_kind);
|
||||||
|
ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind);
|
||||||
|
|
||||||
|
// Increase backing store capacity if that's been decided previously.
|
||||||
|
if (capacity != new_capacity || IsDictionaryElementsKind(from_kind) ||
|
||||||
|
IsFastDoubleElementsKind(from_kind) !=
|
||||||
|
IsFastDoubleElementsKind(to_kind)) {
|
||||||
|
accessor->GrowCapacityAndConvert(object, new_capacity);
|
||||||
|
} else if (from_kind != to_kind) {
|
||||||
|
JSObject::TransitionElementsKind(object, to_kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object->IsJSArray() && index >= array_length) {
|
||||||
|
Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor->Set(object->elements(), index, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> receiver,
|
MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
|
||||||
uint32_t index,
|
uint32_t index,
|
||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes) {
|
PropertyAttributes attributes) {
|
||||||
DCHECK(receiver->map()->is_extensible());
|
DCHECK(object->map()->is_extensible());
|
||||||
|
|
||||||
Isolate* isolate = receiver->GetIsolate();
|
Isolate* isolate = object->GetIsolate();
|
||||||
|
|
||||||
// TODO(verwaest): Use ElementAccessor.
|
// TODO(verwaest): Use ElementAccessor.
|
||||||
Handle<Object> old_length_handle;
|
Handle<Object> old_length_handle;
|
||||||
if (receiver->IsJSArray() && receiver->map()->is_observed()) {
|
if (object->IsJSArray() && object->map()->is_observed()) {
|
||||||
old_length_handle = handle(JSArray::cast(*receiver)->length(), isolate);
|
old_length_handle = handle(JSArray::cast(*object)->length(), isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attributes != NONE) {
|
ElementsKind kind = object->GetElementsKind();
|
||||||
Handle<SeededNumberDictionary> d = JSObject::NormalizeElements(receiver);
|
bool handle_slow = false;
|
||||||
// TODO(verwaest): Move this into NormalizeElements.
|
uint32_t capacity = 0;
|
||||||
d->set_requires_slow_elements();
|
uint32_t new_capacity = 0;
|
||||||
|
if (IsFastElementsKind(kind) || object->HasFastArgumentsElements()) {
|
||||||
|
if (attributes != NONE) {
|
||||||
|
// TODO(verwaest): Move set_requires_slow_elements into NormalizeElements.
|
||||||
|
NormalizeElements(object)->set_requires_slow_elements();
|
||||||
|
handle_slow = true;
|
||||||
|
} else {
|
||||||
|
if (IsSloppyArgumentsElements(kind)) {
|
||||||
|
FixedArray* parameter_map = FixedArray::cast(object->elements());
|
||||||
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
||||||
|
capacity = static_cast<uint32_t>(arguments->length());
|
||||||
|
} else {
|
||||||
|
if (IsFastSmiOrObjectElementsKind(kind)) {
|
||||||
|
EnsureWritableFastElements(object);
|
||||||
|
}
|
||||||
|
capacity = static_cast<uint32_t>(object->elements()->length());
|
||||||
|
}
|
||||||
|
|
||||||
|
new_capacity = capacity;
|
||||||
|
// Check if the capacity of the backing store needs to be increased, or if
|
||||||
|
// a transition to slow elements is necessary.
|
||||||
|
if (index >= capacity) {
|
||||||
|
handle_slow = true;
|
||||||
|
if ((index - capacity) < kMaxGap) {
|
||||||
|
new_capacity = NewElementsCapacity(index + 1);
|
||||||
|
DCHECK_LT(index, new_capacity);
|
||||||
|
handle_slow = object->ShouldConvertToSlowElements(new_capacity);
|
||||||
|
}
|
||||||
|
if (handle_slow) NormalizeElements(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handle_slow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> result = value;
|
if (handle_slow) {
|
||||||
|
DCHECK(object->HasDictionaryElements() ||
|
||||||
switch (receiver->GetElementsKind()) {
|
object->HasDictionaryArgumentsElements());
|
||||||
case FAST_SMI_ELEMENTS:
|
AddDictionaryElement(object, index, value, attributes);
|
||||||
case FAST_ELEMENTS:
|
} else {
|
||||||
case FAST_HOLEY_SMI_ELEMENTS:
|
AddFastElement(object, index, value, kind, capacity, new_capacity);
|
||||||
case FAST_HOLEY_ELEMENTS:
|
|
||||||
AddFastElement(receiver, index, value);
|
|
||||||
break;
|
|
||||||
case FAST_DOUBLE_ELEMENTS:
|
|
||||||
case FAST_HOLEY_DOUBLE_ELEMENTS:
|
|
||||||
AddFastDoubleElement(receiver, index, value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DICTIONARY_ELEMENTS:
|
|
||||||
AddDictionaryElement(receiver, index, value, attributes);
|
|
||||||
break;
|
|
||||||
case SLOPPY_ARGUMENTS_ELEMENTS:
|
|
||||||
AddSloppyArgumentsElement(receiver, index, value, attributes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Elements cannot be added to typed arrays.
|
|
||||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
|
||||||
case EXTERNAL_##TYPE##_ELEMENTS: \
|
|
||||||
case TYPE##_ELEMENTS:
|
|
||||||
|
|
||||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
|
||||||
|
|
||||||
#undef TYPED_ARRAY_CASE
|
|
||||||
UNREACHABLE();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!old_length_handle.is_null() &&
|
if (!old_length_handle.is_null() &&
|
||||||
!old_length_handle->SameValue(
|
!old_length_handle->SameValue(Handle<JSArray>::cast(object)->length())) {
|
||||||
Handle<JSArray>::cast(receiver)->length())) {
|
// |old_length_handle| is kept null above unless the object is observed.
|
||||||
// |old_length_handle| is kept null above unless the receiver is observed.
|
DCHECK(object->map()->is_observed());
|
||||||
DCHECK(receiver->map()->is_observed());
|
Handle<JSArray> array = Handle<JSArray>::cast(object);
|
||||||
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
|
|
||||||
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
||||||
Handle<Object> new_length_handle(array->length(), isolate);
|
Handle<Object> new_length_handle(array->length(), isolate);
|
||||||
uint32_t old_length = 0;
|
uint32_t old_length = 0;
|
||||||
@ -12767,28 +12633,28 @@ MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> receiver,
|
|||||||
|
|
||||||
RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
|
RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
|
||||||
RETURN_ON_EXCEPTION(
|
RETURN_ON_EXCEPTION(
|
||||||
isolate, JSObject::EnqueueChangeRecord(
|
isolate, EnqueueChangeRecord(array, "add", name,
|
||||||
array, "add", name, isolate->factory()->the_hole_value()),
|
isolate->factory()->the_hole_value()),
|
||||||
Object);
|
|
||||||
RETURN_ON_EXCEPTION(
|
|
||||||
isolate, JSObject::EnqueueChangeRecord(
|
|
||||||
array, "update", isolate->factory()->length_string(),
|
|
||||||
old_length_handle),
|
|
||||||
Object);
|
Object);
|
||||||
|
RETURN_ON_EXCEPTION(isolate,
|
||||||
|
EnqueueChangeRecord(array, "update",
|
||||||
|
isolate->factory()->length_string(),
|
||||||
|
old_length_handle),
|
||||||
|
Object);
|
||||||
RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object);
|
RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object);
|
||||||
Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
|
Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
|
||||||
RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted,
|
RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted,
|
||||||
new_length - old_length),
|
new_length - old_length),
|
||||||
Object);
|
Object);
|
||||||
} else if (receiver->map()->is_observed()) {
|
} else if (object->map()->is_observed()) {
|
||||||
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
||||||
RETURN_ON_EXCEPTION(isolate, JSObject::EnqueueChangeRecord(
|
RETURN_ON_EXCEPTION(
|
||||||
receiver, "add", name,
|
isolate, EnqueueChangeRecord(object, "add", name,
|
||||||
isolate->factory()->the_hole_value()),
|
isolate->factory()->the_hole_value()),
|
||||||
Object);
|
Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1114,6 +1114,12 @@ class Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ElementsKind OptimalElementsKind() {
|
||||||
|
if (IsSmi()) return FAST_SMI_ELEMENTS;
|
||||||
|
if (IsNumber()) return FAST_DOUBLE_ELEMENTS;
|
||||||
|
return FAST_ELEMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool FitsRepresentation(Representation representation) {
|
inline bool FitsRepresentation(Representation representation) {
|
||||||
if (FLAG_track_fields && representation.IsNone()) {
|
if (FLAG_track_fields && representation.IsNone()) {
|
||||||
return false;
|
return false;
|
||||||
@ -1777,7 +1783,7 @@ class JSObject: public JSReceiver {
|
|||||||
Handle<Map> map,
|
Handle<Map> map,
|
||||||
Handle<FixedArrayBase> elements);
|
Handle<FixedArrayBase> elements);
|
||||||
inline ElementsKind GetElementsKind();
|
inline ElementsKind GetElementsKind();
|
||||||
inline ElementsAccessor* GetElementsAccessor();
|
ElementsAccessor* GetElementsAccessor();
|
||||||
// Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
|
// Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
|
||||||
inline bool HasFastSmiElements();
|
inline bool HasFastSmiElements();
|
||||||
// Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
|
// Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
|
||||||
@ -1900,9 +1906,6 @@ class JSObject: public JSReceiver {
|
|||||||
static void AddDictionaryElement(Handle<JSObject> object, uint32_t index,
|
static void AddDictionaryElement(Handle<JSObject> object, uint32_t index,
|
||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes);
|
PropertyAttributes attributes);
|
||||||
static void AddSloppyArgumentsElement(Handle<JSObject> object, uint32_t index,
|
|
||||||
Handle<Object> value,
|
|
||||||
PropertyAttributes attributes);
|
|
||||||
static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
|
static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
|
||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes);
|
PropertyAttributes attributes);
|
||||||
@ -1911,11 +1914,6 @@ class JSObject: public JSReceiver {
|
|||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes);
|
PropertyAttributes attributes);
|
||||||
|
|
||||||
static void AddFastElement(Handle<JSObject> object, uint32_t index,
|
|
||||||
Handle<Object> value);
|
|
||||||
static void AddFastDoubleElement(Handle<JSObject> object, uint32_t index,
|
|
||||||
Handle<Object> value);
|
|
||||||
|
|
||||||
static void OptimizeAsPrototype(Handle<JSObject> object,
|
static void OptimizeAsPrototype(Handle<JSObject> object,
|
||||||
PrototypeOptimizationMode mode);
|
PrototypeOptimizationMode mode);
|
||||||
static void ReoptimizeIfPrototype(Handle<JSObject> object);
|
static void ReoptimizeIfPrototype(Handle<JSObject> object);
|
||||||
@ -1990,7 +1988,7 @@ class JSObject: public JSReceiver {
|
|||||||
|
|
||||||
static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
|
static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
|
||||||
|
|
||||||
static inline void ValidateElements(Handle<JSObject> object);
|
static void ValidateElements(Handle<JSObject> object);
|
||||||
|
|
||||||
// Makes sure that this object can contain HeapObject as elements.
|
// Makes sure that this object can contain HeapObject as elements.
|
||||||
static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
|
static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "src/v8.h"
|
#include "src/v8.h"
|
||||||
|
|
||||||
#include "src/arguments.h"
|
#include "src/arguments.h"
|
||||||
|
#include "src/elements.h"
|
||||||
#include "src/messages.h"
|
#include "src/messages.h"
|
||||||
#include "src/runtime/runtime-utils.h"
|
#include "src/runtime/runtime-utils.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user