Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index e1318bcc3f1a452b00addc58aa3a7c87d8df9c5b..63c1aa9a58785bcbcbb715b7115b15f7465a3736 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -33,6 +33,7 @@ |
#include "codegen.h" |
#include "debug.h" |
#include "deoptimizer.h" |
+#include "elements.h" |
#include "execution.h" |
#include "full-codegen.h" |
#include "hydrogen.h" |
@@ -2923,7 +2924,7 @@ MaybeObject* JSObject::NormalizeElements() { |
// exceed the capacity of new space, and we would fail repeatedly |
// trying to convert the FixedDoubleArray. |
MaybeObject* maybe_value_object = |
- GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); |
+ GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); |
if (!maybe_value_object->ToObject(&value)) return maybe_value_object; |
} |
} else { |
@@ -4898,7 +4899,7 @@ MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) { |
Object* obj; |
for (int y = 0; y < len1; y++) { |
if (!other->is_the_hole(y)) { |
- MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
+ MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y)); |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
if (!HasKey(this, obj)) extra++; |
} |
@@ -4927,7 +4928,7 @@ MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) { |
int index = 0; |
for (int y = 0; y < len1; y++) { |
if (!other->is_the_hole(y)) { |
- MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
+ MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y)); |
if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
if (!HasKey(this, obj)) { |
result->set(len0 + index, obj); |
@@ -7602,7 +7603,8 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, |
// exceed the capacity of new space, and we would fail repeatedly |
// trying to convert the FixedDoubleArray. |
MaybeObject* maybe_value_object = |
- GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); |
+ GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i), |
+ TENURED); |
if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; |
// Force write barrier. It's not worth trying to exploit |
// elems->GetWriteBarrierMode(), since it requires an |
@@ -8945,71 +8947,6 @@ MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
} |
-MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
- uint32_t index) { |
- // Get element works for both JSObject and JSArray since |
- // JSArray::length cannot change. |
- switch (GetElementsKind()) { |
- case FAST_ELEMENTS: { |
- FixedArray* elms = FixedArray::cast(elements()); |
- if (index < static_cast<uint32_t>(elms->length())) { |
- Object* value = elms->get(index); |
- if (!value->IsTheHole()) return value; |
- } |
- break; |
- } |
- case FAST_DOUBLE_ELEMENTS: { |
- FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
- if (index < static_cast<uint32_t>(elms->length())) { |
- if (!elms->is_the_hole(index)) { |
- return GetHeap()->NumberFromDouble(elms->get(index)); |
- } |
- } |
- break; |
- } |
- case EXTERNAL_PIXEL_ELEMENTS: |
- case EXTERNAL_BYTE_ELEMENTS: |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
- case EXTERNAL_SHORT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
- case EXTERNAL_INT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
- case EXTERNAL_FLOAT_ELEMENTS: |
- case EXTERNAL_DOUBLE_ELEMENTS: { |
- MaybeObject* maybe_value = GetExternalElement(index); |
- Object* value; |
- if (!maybe_value->ToObject(&value)) return maybe_value; |
- if (!value->IsUndefined()) return value; |
- break; |
- } |
- case DICTIONARY_ELEMENTS: { |
- NumberDictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindEntry(index); |
- if (entry != NumberDictionary::kNotFound) { |
- Object* element = dictionary->ValueAt(entry); |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- if (details.type() == CALLBACKS) { |
- return GetElementWithCallback(receiver, |
- element, |
- index, |
- this); |
- } |
- return element; |
- } |
- break; |
- } |
- case NON_STRICT_ARGUMENTS_ELEMENTS: |
- UNIMPLEMENTED(); |
- break; |
- } |
- |
- // Continue searching via the prototype chain. |
- Object* pt = GetPrototype(); |
- if (pt->IsNull()) return GetHeap()->undefined_value(); |
- return pt->GetElementWithReceiver(receiver, index); |
-} |
- |
- |
MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
uint32_t index) { |
Isolate* isolate = GetIsolate(); |
@@ -9037,10 +8974,18 @@ MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
} |
- MaybeObject* raw_result = |
- holder_handle->GetElementPostInterceptor(*this_handle, index); |
+ Heap* heap = holder_handle->GetHeap(); |
+ ElementsAccessor* handler = holder_handle->GetElementsAccessor(); |
+ MaybeObject* raw_result = handler->GetWithReceiver(*holder_handle, |
+ *this_handle, |
+ index); |
+ if (raw_result != heap->the_hole_value()) return raw_result; |
+ |
RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
- return raw_result; |
+ |
+ Object* pt = holder_handle->GetPrototype(); |
+ if (pt == heap->null_value()) return heap->undefined_value(); |
+ return pt->GetElementWithReceiver(*this_handle, index); |
} |
@@ -9059,193 +9004,20 @@ MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
return GetElementWithInterceptor(receiver, index); |
} |
- // Get element works for both JSObject and JSArray since |
- // JSArray::length cannot change. |
- switch (GetElementsKind()) { |
- case FAST_ELEMENTS: { |
- FixedArray* elms = FixedArray::cast(elements()); |
- if (index < static_cast<uint32_t>(elms->length())) { |
- Object* value = elms->get(index); |
- if (!value->IsTheHole()) return value; |
- } |
- break; |
- } |
- case FAST_DOUBLE_ELEMENTS: { |
- FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
- if (index < static_cast<uint32_t>(elms->length())) { |
- if (!elms->is_the_hole(index)) { |
- double double_value = elms->get(index); |
- return GetHeap()->NumberFromDouble(double_value); |
- } |
- } |
- break; |
- } |
- case EXTERNAL_PIXEL_ELEMENTS: |
- case EXTERNAL_BYTE_ELEMENTS: |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
- case EXTERNAL_SHORT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
- case EXTERNAL_INT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
- case EXTERNAL_FLOAT_ELEMENTS: |
- case EXTERNAL_DOUBLE_ELEMENTS: { |
- MaybeObject* maybe_value = GetExternalElement(index); |
- Object* value; |
- if (!maybe_value->ToObject(&value)) return maybe_value; |
- if (!value->IsUndefined()) return value; |
- break; |
- } |
- case DICTIONARY_ELEMENTS: { |
- NumberDictionary* dictionary = element_dictionary(); |
- int entry = dictionary->FindEntry(index); |
- if (entry != NumberDictionary::kNotFound) { |
- Object* element = dictionary->ValueAt(entry); |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- if (details.type() == CALLBACKS) { |
- return GetElementWithCallback(receiver, |
- element, |
- index, |
- this); |
- } |
- return element; |
- } |
- break; |
- } |
- case NON_STRICT_ARGUMENTS_ELEMENTS: { |
- FixedArray* parameter_map = FixedArray::cast(elements()); |
- uint32_t length = parameter_map->length(); |
- Object* probe = |
- (index < length - 2) ? parameter_map->get(index + 2) : NULL; |
- if (probe != NULL && !probe->IsTheHole()) { |
- Context* context = Context::cast(parameter_map->get(0)); |
- int context_index = Smi::cast(probe)->value(); |
- ASSERT(!context->get(context_index)->IsTheHole()); |
- return context->get(context_index); |
- } else { |
- // Object is not mapped, defer to the arguments. |
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
- if (arguments->IsDictionary()) { |
- NumberDictionary* dictionary = NumberDictionary::cast(arguments); |
- int entry = dictionary->FindEntry(index); |
- if (entry != NumberDictionary::kNotFound) { |
- Object* element = dictionary->ValueAt(entry); |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- if (details.type() == CALLBACKS) { |
- return GetElementWithCallback(receiver, |
- element, |
- index, |
- this); |
- } |
- return element; |
- } |
- } else if (index < static_cast<uint32_t>(arguments->length())) { |
- Object* value = arguments->get(index); |
- if (!value->IsTheHole()) return value; |
- } |
- } |
- break; |
- } |
+ Heap* heap = GetHeap(); |
+ if (elements() != heap->empty_fixed_array()) { |
+ MaybeObject* result = GetElementsAccessor()->GetWithReceiver(this, |
+ receiver, |
+ index); |
+ if (result != heap->the_hole_value()) return result; |
} |
Object* pt = GetPrototype(); |
- Heap* heap = GetHeap(); |
if (pt == heap->null_value()) return heap->undefined_value(); |
return pt->GetElementWithReceiver(receiver, index); |
} |
-MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
- // Get element works for both JSObject and JSArray since |
- // JSArray::length cannot change. |
- switch (GetElementsKind()) { |
- case EXTERNAL_PIXEL_ELEMENTS: { |
- ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
- if (index < static_cast<uint32_t>(pixels->length())) { |
- uint8_t value = pixels->get(index); |
- return Smi::FromInt(value); |
- } |
- break; |
- } |
- case EXTERNAL_BYTE_ELEMENTS: { |
- ExternalByteArray* array = ExternalByteArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- int8_t value = array->get(index); |
- return Smi::FromInt(value); |
- } |
- break; |
- } |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
- ExternalUnsignedByteArray* array = |
- ExternalUnsignedByteArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- uint8_t value = array->get(index); |
- return Smi::FromInt(value); |
- } |
- break; |
- } |
- case EXTERNAL_SHORT_ELEMENTS: { |
- ExternalShortArray* array = ExternalShortArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- int16_t value = array->get(index); |
- return Smi::FromInt(value); |
- } |
- break; |
- } |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
- ExternalUnsignedShortArray* array = |
- ExternalUnsignedShortArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- uint16_t value = array->get(index); |
- return Smi::FromInt(value); |
- } |
- break; |
- } |
- case EXTERNAL_INT_ELEMENTS: { |
- ExternalIntArray* array = ExternalIntArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- int32_t value = array->get(index); |
- return GetHeap()->NumberFromInt32(value); |
- } |
- break; |
- } |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
- ExternalUnsignedIntArray* array = |
- ExternalUnsignedIntArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- uint32_t value = array->get(index); |
- return GetHeap()->NumberFromUint32(value); |
- } |
- break; |
- } |
- case EXTERNAL_FLOAT_ELEMENTS: { |
- ExternalFloatArray* array = ExternalFloatArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- float value = array->get(index); |
- return GetHeap()->AllocateHeapNumber(value); |
- } |
- break; |
- } |
- case EXTERNAL_DOUBLE_ELEMENTS: { |
- ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); |
- if (index < static_cast<uint32_t>(array->length())) { |
- double value = array->get(index); |
- return GetHeap()->AllocateHeapNumber(value); |
- } |
- break; |
- } |
- case FAST_DOUBLE_ELEMENTS: |
- case FAST_ELEMENTS: |
- case DICTIONARY_ELEMENTS: |
- UNREACHABLE(); |
- break; |
- case NON_STRICT_ARGUMENTS_ELEMENTS: |
- UNIMPLEMENTED(); |
- break; |
- } |
- return GetHeap()->undefined_value(); |
-} |
- |
- |
bool JSObject::HasDenseElements() { |
int capacity = 0; |
int used = 0; |
@@ -10728,7 +10500,7 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
if (elements->is_the_hole(holes)) { |
holes--; |
} else { |
- elements->set(i, elements->get(holes)); |
+ elements->set(i, elements->get_scalar(holes)); |
break; |
} |
} |