// -- lr : return address
// -----------------------------------
//
- // This accepts as a receiver anything JSObject::SetElementsLength accepts
- // (currently anything except for external and pixel arrays which means
- // anything with elements of FixedArray type.), but currently is restricted
- // to JSArray.
- // Value must be a number, but only smis are accepted as the most common case.
+ // This accepts as a receiver anything JSArray::SetElementsLength accepts
+ // (currently anything except for external arrays which means anything with
+ // elements of FixedArray type). Value must be a number, but only smis are
+ // accepted as the most common case.
Label miss;
__ CompareObjectType(scratch, scratch, scratch, FIXED_ARRAY_TYPE);
__ b(ne, &miss);
+ // Check that the array has fast properties, otherwise the length
+ // property might have been redefined.
+ __ ldr(scratch, FieldMemOperand(receiver, JSArray::kPropertiesOffset));
+ __ ldr(scratch, FieldMemOperand(scratch, FixedArray::kMapOffset));
+ __ CompareRoot(scratch, Heap::kHashTableMapRootIndex);
+ __ b(eq, &miss);
+
// Check that value is a smi.
__ JumpIfNotSmi(value, &miss);
// -- esp[0] : return address
// -----------------------------------
//
- // This accepts as a receiver anything JSObject::SetElementsLength accepts
+ // This accepts as a receiver anything JSArray::SetElementsLength accepts
// (currently anything except for external arrays which means anything with
- // elements of FixedArray type.), but currently is restricted to JSArray.
- // Value must be a number, but only smis are accepted as the most common case.
+ // elements of FixedArray type). Value must be a number, but only smis are
+ // accepted as the most common case.
Label miss;
__ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
__ j(not_equal, &miss);
+ // Check that the array has fast properties, otherwise the length
+ // property might have been redefined.
+ __ mov(scratch, FieldOperand(receiver, JSArray::kPropertiesOffset));
+ __ CompareRoot(FieldOperand(scratch, FixedArray::kMapOffset),
+ Heap::kHashTableMapRootIndex);
+ __ j(equal, &miss);
+
// Check that value is a smi.
__ JumpIfNotSmi(value, &miss);
}
+void MacroAssembler::CompareRoot(const Operand& with,
+ Heap::RootListIndex index) {
+ // see ROOT_ACCESSOR macro in factory.h
+ Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
+ cmp(with, value);
+}
+
+
void MacroAssembler::CmpObjectType(Register heap_object,
InstanceType type,
Register map) {
void SafeSet(Register dst, const Immediate& x);
void SafePush(const Immediate& x);
- // Compare a register against a known root, e.g. undefined, null, true, ...
+ // Compare against a known root, e.g. undefined, null, true, ...
void CompareRoot(Register with, Heap::RootListIndex index);
+ void CompareRoot(const Operand& with, Heap::RootListIndex index);
// Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map.
return *value;
}
- // Use specialized code for setting the length of arrays.
- if (receiver->IsJSArray()
- && name->Equals(isolate()->heap()->length_symbol())
- && Handle<JSArray>::cast(receiver)->AllowsSetElementsLength()) {
+ // Use specialized code for setting the length of arrays with fast
+ // properties. Slow properties might indicate redefinition of the
+ // length property.
+ if (receiver->IsJSArray() &&
+ name->Equals(isolate()->heap()->length_symbol()) &&
+ Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
+ receiver->HasFastProperties()) {
#ifdef DEBUG
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
#endif
NoHandleAllocation nha;
ASSERT(args.length() == 2);
- JSObject* receiver = JSObject::cast(args[0]);
+ JSArray* receiver = JSArray::cast(args[0]);
Object* len = args[1];
// The generated code should filter out non-Smis before we get here.
ASSERT(len->IsSmi());
+#ifdef DEBUG
+ // The length property has to be a writable callback property.
+ LookupResult debug_lookup(isolate);
+ receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup);
+ ASSERT(debug_lookup.type() == CALLBACKS && !debug_lookup.IsReadOnly());
+#endif
+
Object* result;
{ MaybeObject* maybe_result = receiver->SetElementsLength(len);
if (!maybe_result->ToObject(&result)) return maybe_result;
// -- ra : return address
// -----------------------------------
//
- // This accepts as a receiver anything JSObject::SetElementsLength accepts
- // (currently anything except for external and pixel arrays which means
- // anything with elements of FixedArray type.), but currently is restricted
- // to JSArray.
- // Value must be a number, but only smis are accepted as the most common case.
+ // This accepts as a receiver anything JSArray::SetElementsLength accepts
+ // (currently anything except for external arrays which means anything with
+ // elements of FixedArray type). Value must be a number, but only smis are
+ // accepted as the most common case.
Label miss;
__ GetObjectType(scratch, scratch, scratch);
__ Branch(&miss, ne, scratch, Operand(FIXED_ARRAY_TYPE));
+ // Check that the array has fast properties, otherwise the length
+ // property might have been redefined.
+ // TODO(mstarzinger): Port this check to MIPS.
+
// Check that value is a smi.
__ JumpIfNotSmi(value, &miss);
}
-bool JSObject::AllowsSetElementsLength() {
- bool result = elements()->IsFixedArray() ||
- elements()->IsFixedDoubleArray();
- ASSERT(result == !HasExternalArrayElements());
- return result;
-}
-
-
MaybeObject* JSObject::EnsureWritableFastElements() {
ASSERT(HasFastTypeElements());
FixedArray* elems = FixedArray::cast(elements());
}
+bool JSArray::AllowsSetElementsLength() {
+ bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
+ ASSERT(result == !HasExternalArrayElements());
+ return result;
+}
+
+
MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
MaybeObject* maybe_result = EnsureCanContainElements(
storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
}
-MaybeObject* JSObject::SetElementsLength(Object* len) {
+MaybeObject* JSArray::SetElementsLength(Object* len) {
// We should never end in here with a pixel or external array.
ASSERT(AllowsSetElementsLength());
return GetElementsAccessor()->SetLength(this, len);
inline bool HasExternalDoubleElements();
bool HasFastArgumentsElements();
bool HasDictionaryArgumentsElements();
- inline bool AllowsSetElementsLength();
inline NumberDictionary* element_dictionary(); // Gets slow elements.
// Requires: HasFastElements().
bool HasRealElementProperty(uint32_t index);
bool HasRealNamedCallbackProperty(String* key);
- // Initializes the array to a certain length
- MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
-
// Get the header size for a JSObject. Used to compute the index of
// internal fields as well as the number of internal fields.
inline int GetHeaderSize();
// capacity is non-zero.
MUST_USE_RESULT MaybeObject* Initialize(int capacity);
+ // Initializes the array to a certain length.
+ inline bool AllowsSetElementsLength();
+ MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
+
// Set the content of the array to the content of storage.
inline MaybeObject* SetContent(FixedArrayBase* storage);
// -- rsp[0] : return address
// -----------------------------------
//
- // This accepts as a receiver anything JSObject::SetElementsLength accepts
- // (currently anything except for external and pixel arrays which means
- // anything with elements of FixedArray type.), but currently is restricted
- // to JSArray.
- // Value must be a number, but only smis are accepted as the most common case.
+ // This accepts as a receiver anything JSArray::SetElementsLength accepts
+ // (currently anything except for external arrays which means anything with
+ // elements of FixedArray type). Value must be a number, but only smis are
+ // accepted as the most common case.
Label miss;
__ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
__ j(not_equal, &miss);
+ // Check that the array has fast properties, otherwise the length
+ // property might have been redefined.
+ __ movq(scratch, FieldOperand(receiver, JSArray::kPropertiesOffset));
+ __ CompareRoot(FieldOperand(scratch, FixedArray::kMapOffset),
+ Heap::kHashTableMapRootIndex);
+ __ j(equal, &miss);
+
// Check that value is a smi.
__ JumpIfNotSmi(value, &miss);
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1530
S15.3.3.1_A4: FAIL
-# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1756
-15.2.3.6-4-167: FAIL || PASS
-15.2.3.6-4-181: FAIL || PASS
-15.2.3.7-6-a-163: FAIL || PASS
-15.2.3.7-6-a-164: FAIL || PASS
-15.2.3.7-6-a-176: FAIL || PASS
-15.2.3.7-6-a-177: FAIL || PASS
-
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1772
15.2.3.6-4-292-1: FAIL
15.2.3.6-4-293-2: FAIL