Index: src/objects-inl.h |
diff --git a/src/objects-inl.h b/src/objects-inl.h |
index 311afc0bc7b1076d95a43ffa9f5325db1c3c173a..7c98eb1f5f5a3a55b0953f2647ce9d6decff996a 100644 |
--- a/src/objects-inl.h |
+++ b/src/objects-inl.h |
@@ -41,6 +41,7 @@ |
#include "conversions-inl.h" |
#include "heap.h" |
#include "isolate.h" |
+#include "heap-inl.h" |
#include "property.h" |
#include "spaces.h" |
#include "store-buffer.h" |
@@ -85,6 +86,13 @@ PropertyDetails PropertyDetails::AsDeleted() { |
} |
+#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \ |
+ template<> \ |
+ type* type::cast(Object* object) { \ |
+ SLOW_ASSERT(object->Is##type()); \ |
+ return reinterpret_cast<type*>(object); \ |
+ } |
+ |
#define INT_ACCESSORS(holder, name, offset) \ |
int holder::name() { return READ_INT_FIELD(this, offset); } \ |
void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } |
@@ -133,7 +141,8 @@ PropertyDetails PropertyDetails::AsDeleted() { |
bool Object::IsFixedArrayBase() { |
- return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray(); |
+ return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() |
+ || IsFixedTypedArrayBase() || IsExternalArray(); |
Toon Verwaest
2013/12/23 10:40:32
|| on previous line.
Dmitry Lomov (no reviews)
2014/01/07 15:48:43
Done.
|
} |
@@ -261,7 +270,8 @@ bool Object::IsExternalTwoByteString() { |
bool Object::HasValidElements() { |
// Dictionary is covered under FixedArray. |
- return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray(); |
+ return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() |
+ || IsFixedTypedArrayBase(); |
Toon Verwaest
2013/12/23 10:40:32
|| on previous line.
Dmitry Lomov (no reviews)
2014/01/07 15:48:43
Done.
|
} |
@@ -487,6 +497,27 @@ TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE) |
TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE) |
+bool Object::IsFixedTypedArrayBase() { |
+ if (!Object::IsHeapObject()) |
+ return false; |
+ InstanceType instance_type = |
+ HeapObject::cast(this)->map()->instance_type(); |
+ return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && |
+ instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE); |
+} |
+ |
+ |
+TYPE_CHECKER(FixedUint8Array, FIXED_UINT8_ARRAY_TYPE) |
+TYPE_CHECKER(FixedInt8Array, FIXED_INT8_ARRAY_TYPE) |
+TYPE_CHECKER(FixedUint16Array, FIXED_UINT16_ARRAY_TYPE) |
+TYPE_CHECKER(FixedInt16Array, FIXED_INT16_ARRAY_TYPE) |
+TYPE_CHECKER(FixedUint32Array, FIXED_UINT32_ARRAY_TYPE) |
+TYPE_CHECKER(FixedInt32Array, FIXED_INT32_ARRAY_TYPE) |
+TYPE_CHECKER(FixedFloat32Array, FIXED_FLOAT32_ARRAY_TYPE) |
+TYPE_CHECKER(FixedFloat64Array, FIXED_FLOAT64_ARRAY_TYPE) |
+TYPE_CHECKER(FixedUint8ClampedArray, FIXED_UINT8_CLAMPED_ARRAY_TYPE) |
+ |
+ |
bool MaybeObject::IsFailure() { |
return HAS_FAILURE_TAG(this); |
} |
@@ -1941,8 +1972,7 @@ void Object::VerifyApiCallResultType() { |
FixedArrayBase* FixedArrayBase::cast(Object* object) { |
- ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray() || |
- object->IsConstantPoolArray()); |
+ ASSERT(object->IsFixedArrayBase()); |
return reinterpret_cast<FixedArrayBase*>(object); |
} |
@@ -2625,6 +2655,7 @@ void SeededNumberDictionary::set_requires_slow_elements() { |
CAST_ACCESSOR(FixedArray) |
CAST_ACCESSOR(FixedDoubleArray) |
+CAST_ACCESSOR(FixedTypedArrayBase) |
CAST_ACCESSOR(ConstantPoolArray) |
CAST_ACCESSOR(DescriptorArray) |
CAST_ACCESSOR(DeoptimizationInputData) |
@@ -2694,6 +2725,14 @@ CAST_ACCESSOR(ExternalPixelArray) |
CAST_ACCESSOR(Struct) |
CAST_ACCESSOR(AccessorInfo) |
+template <class Traits> |
+FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) { |
+ SLOW_ASSERT(object->IsHeapObject() && |
+ HeapObject::cast(object)->map()->instance_type() |
+ == Traits::kInstanceType); |
+ return reinterpret_cast<FixedTypedArray<Traits>*>(object); |
+} |
+ |
#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
STRUCT_LIST(MAKE_STRUCT_CAST) |
@@ -3469,6 +3508,133 @@ void ExternalDoubleArray::set(int index, double value) { |
} |
+int FixedTypedArrayBase::size() { |
+ InstanceType instance_type = map()->instance_type(); |
+ int element_size; |
+ switch (instance_type) { |
+ case FIXED_UINT8_ARRAY_TYPE: |
+ case FIXED_INT8_ARRAY_TYPE: |
+ case FIXED_UINT8_CLAMPED_ARRAY_TYPE: |
+ element_size = 1; |
+ break; |
+ case FIXED_UINT16_ARRAY_TYPE: |
+ case FIXED_INT16_ARRAY_TYPE: |
+ element_size = 2; |
+ break; |
+ case FIXED_UINT32_ARRAY_TYPE: |
+ case FIXED_INT32_ARRAY_TYPE: |
+ case FIXED_FLOAT32_ARRAY_TYPE: |
+ element_size = 4; |
+ break; |
+ case FIXED_FLOAT64_ARRAY_TYPE: |
+ element_size = 8; |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ return 0; |
+ } |
+ return kDataOffset + length() * element_size; |
+} |
+ |
+ |
+template <class Traits> |
+typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) { |
+ ASSERT((index >= 0) && (index < this->length())); |
+ ElementType* ptr = reinterpret_cast<ElementType*>( |
+ FIELD_ADDR(this, kDataOffset)); |
+ return ptr[index]; |
+} |
+ |
+template <class Traits> |
+void FixedTypedArray<Traits>::set(int index, ElementType value) { |
+ ASSERT((index >= 0) && (index < this->length())); |
+ ElementType* ptr = reinterpret_cast<ElementType*>( |
+ FIELD_ADDR(this, kDataOffset)); |
+ ptr[index] = value; |
+} |
+ |
+ |
+template <class Traits> |
+MaybeObject* FixedTypedArray<Traits>::get(int index) { |
+ return Traits::ToObject(GetHeap(), get_scalar(index)); |
+} |
+ |
+template <class Traits> |
+MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { |
+ ElementType cast_value = Traits::defaultValue(); |
+ if (index < static_cast<uint32_t>(length())) { |
+ if (value->IsSmi()) { |
+ int int_value = Smi::cast(value)->value(); |
+ cast_value = static_cast<ElementType>(int_value); |
+ } else if (value->IsHeapNumber()) { |
+ double double_value = HeapNumber::cast(value)->value(); |
+ cast_value = static_cast<ElementType>(DoubleToInt32(double_value)); |
+ } else { |
+ // Clamp undefined to zero (default). All other types have been |
Toon Verwaest
2013/12/23 10:40:32
I'd just write "Clamp undefined to the default val
Dmitry Lomov (no reviews)
2014/01/07 15:48:43
Done.
|
+ // converted to a number type further up in the call chain. |
+ ASSERT(value->IsUndefined()); |
+ } |
+ set(index, cast_value); |
+ } |
+ return Traits::ToObject(GetHeap(), cast_value); |
+} |
+ |
+template <class Traits> |
+Handle<Object> FixedTypedArray<Traits>::SetValue( |
+ Handle<FixedTypedArray<Traits> > array, |
+ uint32_t index, |
+ Handle<Object> value) { |
+ CALL_HEAP_FUNCTION(array->GetIsolate(), |
+ array->SetValue(index, *value), |
+ Object); |
+} |
+ |
+ |
+MaybeObject* Uint8ArrayTraits::ToObject(Heap*, uint8_t scalar) { |
+ return Smi::FromInt(scalar); |
+} |
+ |
+ |
+MaybeObject* Uint8ClampedArrayTraits::ToObject(Heap*, uint8_t scalar) { |
+ return Smi::FromInt(scalar); |
+} |
+ |
+ |
+MaybeObject* Int8ArrayTraits::ToObject(Heap*, int8_t scalar) { |
+ return Smi::FromInt(scalar); |
+} |
+ |
+ |
+MaybeObject* Uint16ArrayTraits::ToObject(Heap*, uint16_t scalar) { |
+ return Smi::FromInt(scalar); |
+} |
+ |
+ |
+MaybeObject* Int16ArrayTraits::ToObject(Heap*, int16_t scalar) { |
+ return Smi::FromInt(scalar); |
+} |
+ |
+ |
+MaybeObject* Uint32ArrayTraits::ToObject(Heap* heap, uint32_t scalar) { |
+ return heap->NumberFromUint32(scalar); |
+} |
+ |
+ |
+MaybeObject* Int32ArrayTraits::ToObject(Heap* heap, int32_t scalar) { |
+ return heap->NumberFromInt32(scalar); |
+} |
+ |
+ |
+MaybeObject* Float32ArrayTraits::ToObject(Heap* heap, float scalar) { |
+ return heap->NumberFromDouble(scalar); |
+} |
+ |
+ |
+MaybeObject* Float64ArrayTraits::ToObject(Heap* heap, double scalar) { |
+ return heap->NumberFromDouble(scalar); |
+} |
+ |
+ |
int Map::visitor_id() { |
return READ_BYTE_FIELD(this, kVisitorIdOffset); |
} |
@@ -3529,6 +3695,10 @@ int HeapObject::SizeFromMap(Map* map) { |
reinterpret_cast<ConstantPoolArray*>(this)->count_of_ptr_entries(), |
reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries()); |
} |
+ if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && |
+ instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) { |
+ return reinterpret_cast<FixedTypedArrayBase*>(this)->size(); |
+ } |
ASSERT(instance_type == CODE_TYPE); |
return reinterpret_cast<Code*>(this)->CodeSize(); |
} |
@@ -5680,6 +5850,13 @@ EXTERNAL_ELEMENTS_CHECK(Double, |
EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE) |
+bool JSObject::HasFixedTypedArrayElements() { |
+ HeapObject* array = elements(); |
+ ASSERT(array != NULL); |
+ return array->IsFixedTypedArrayBase(); |
+} |
+ |
+ |
bool JSObject::HasNamedInterceptor() { |
return map()->has_named_interceptor(); |
} |