First implementation of fast path for instantiation of array literals composed of doubles.
Review URL: https://chromiumcodereview.appspot.com/9814006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11114 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
4cb600962f
commit
c39c2089a7
@ -4616,34 +4616,51 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store header.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
if (has_elements) {
|
||||
// Copy elements backing store header.
|
||||
__ LoadHeapObject(source, elements);
|
||||
for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
|
||||
__ ldr(r2, FieldMemOperand(source, i));
|
||||
__ str(r2, FieldMemOperand(result, elements_offset + i));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store content.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
int elements_length = has_elements ? elements->length() : 0;
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ add(r2, result, Operand(*offset));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
// Copy elements backing store content.
|
||||
int elements_length = has_elements ? elements->length() : 0;
|
||||
if (elements->IsFixedDoubleArray()) {
|
||||
Handle<FixedDoubleArray> double_array =
|
||||
Handle<FixedDoubleArray>::cast(elements);
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int64_t value = double_array->get_representation(i);
|
||||
// We only support little endian mode...
|
||||
int32_t value_low = value & 0xFFFFFFFF;
|
||||
int32_t value_high = value >> 32;
|
||||
int total_offset =
|
||||
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
|
||||
__ mov(r2, Operand(value_low));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
__ mov(r2, Operand(value_high));
|
||||
__ str(r2, FieldMemOperand(result, total_offset + 4));
|
||||
}
|
||||
} else if (elements->IsFixedArray()) {
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ add(r2, result, Operand(*offset));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
} else {
|
||||
__ mov(r2, Operand(value));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__ mov(r2, Operand(value));
|
||||
__ str(r2, FieldMemOperand(result, total_offset));
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3683,22 +3683,27 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
||||
Handle<FixedArrayBase> elements(boilerplate->elements());
|
||||
if (elements->length() > 0 &&
|
||||
elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) {
|
||||
if (!boilerplate->HasFastElements()) return false;
|
||||
int length = elements->length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if ((*max_properties)-- == 0) return false;
|
||||
Handle<Object> value = JSObject::GetElement(boilerplate, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
if (!IsFastLiteral(value_object,
|
||||
max_depth - 1,
|
||||
max_properties,
|
||||
total_size)) {
|
||||
return false;
|
||||
if (boilerplate->HasFastDoubleElements()) {
|
||||
*total_size += FixedDoubleArray::SizeFor(elements->length());
|
||||
} else if (boilerplate->HasFastElements()) {
|
||||
int length = elements->length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if ((*max_properties)-- == 0) return false;
|
||||
Handle<Object> value = JSObject::GetElement(boilerplate, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
if (!IsFastLiteral(value_object,
|
||||
max_depth - 1,
|
||||
max_properties,
|
||||
total_size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
*total_size += FixedArray::SizeFor(length);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
*total_size += FixedArray::SizeFor(length);
|
||||
}
|
||||
|
||||
Handle<FixedArray> properties(boilerplate->properties());
|
||||
|
@ -4470,33 +4470,47 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store header.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
if (has_elements) {
|
||||
// Copy elements backing store header.
|
||||
__ LoadHeapObject(source, elements);
|
||||
for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
|
||||
__ mov(ecx, FieldOperand(source, i));
|
||||
__ mov(FieldOperand(result, elements_offset + i), ecx);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store content.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
int elements_length = has_elements ? elements->length() : 0;
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ lea(ecx, Operand(result, *offset));
|
||||
__ mov(FieldOperand(result, total_offset), ecx);
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
|
||||
__ mov(FieldOperand(result, total_offset), ecx);
|
||||
// Copy elements backing store content.
|
||||
int elements_length = elements->length();
|
||||
if (elements->IsFixedDoubleArray()) {
|
||||
Handle<FixedDoubleArray> double_array =
|
||||
Handle<FixedDoubleArray>::cast(elements);
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int64_t value = double_array->get_representation(i);
|
||||
int32_t value_low = value & 0xFFFFFFFF;
|
||||
int32_t value_high = value >> 32;
|
||||
int total_offset =
|
||||
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
|
||||
__ mov(FieldOperand(result, total_offset), Immediate(value_low));
|
||||
__ mov(FieldOperand(result, total_offset + 4), Immediate(value_high));
|
||||
}
|
||||
} else if (elements->IsFixedArray()) {
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ lea(ecx, Operand(result, *offset));
|
||||
__ mov(FieldOperand(result, total_offset), ecx);
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
|
||||
__ mov(FieldOperand(result, total_offset), ecx);
|
||||
} else {
|
||||
__ mov(FieldOperand(result, total_offset), Immediate(value));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__ mov(FieldOperand(result, total_offset), Immediate(value));
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -944,6 +944,12 @@ MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
|
||||
#define WRITE_UINT32_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_INT64_FIELD(p, offset) \
|
||||
(*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
|
||||
|
||||
#define WRITE_INT64_FIELD(p, offset, value) \
|
||||
(*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
|
||||
|
||||
#define READ_SHORT_FIELD(p, offset) \
|
||||
(*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
|
||||
|
||||
@ -1701,6 +1707,12 @@ double FixedDoubleArray::get_scalar(int index) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t FixedDoubleArray::get_representation(int index) {
|
||||
ASSERT(map() != HEAP->fixed_cow_array_map() &&
|
||||
map() != HEAP->fixed_array_map());
|
||||
ASSERT(index >= 0 && index < this->length());
|
||||
return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
|
||||
}
|
||||
|
||||
MaybeObject* FixedDoubleArray::get(int index) {
|
||||
if (is_the_hole(index)) {
|
||||
|
@ -2345,6 +2345,7 @@ class FixedDoubleArray: public FixedArrayBase {
|
||||
public:
|
||||
// Setter and getter for elements.
|
||||
inline double get_scalar(int index);
|
||||
inline int64_t get_representation(int index);
|
||||
MUST_USE_RESULT inline MaybeObject* get(int index);
|
||||
inline void set(int index, double value);
|
||||
inline void set_the_hole(int index);
|
||||
|
@ -4238,34 +4238,46 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store header.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
if (has_elements) {
|
||||
// Copy elements backing store header.
|
||||
__ LoadHeapObject(source, elements);
|
||||
for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
|
||||
__ movq(rcx, FieldOperand(source, i));
|
||||
__ movq(FieldOperand(result, elements_offset + i), rcx);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy elements backing store content.
|
||||
ASSERT(!has_elements || elements->IsFixedArray());
|
||||
int elements_length = has_elements ? elements->length() : 0;
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ lea(rcx, Operand(result, *offset));
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(rcx, Handle<HeapObject>::cast(value));
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
// Copy elements backing store content.
|
||||
int elements_length = elements->length();
|
||||
if (elements->IsFixedDoubleArray()) {
|
||||
Handle<FixedDoubleArray> double_array =
|
||||
Handle<FixedDoubleArray>::cast(elements);
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int64_t value = double_array->get_representation(i);
|
||||
int total_offset =
|
||||
elements_offset + FixedDoubleArray::OffsetOfElementAt(i);
|
||||
__ movq(rcx, value, RelocInfo::NONE);
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
}
|
||||
} else if (elements->IsFixedArray()) {
|
||||
for (int i = 0; i < elements_length; i++) {
|
||||
int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
|
||||
Handle<Object> value = JSObject::GetElement(object, i);
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
||||
__ lea(rcx, Operand(result, *offset));
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
__ LoadHeapObject(source, value_object);
|
||||
EmitDeepCopy(value_object, result, source, offset);
|
||||
} else if (value->IsHeapObject()) {
|
||||
__ LoadHeapObject(rcx, Handle<HeapObject>::cast(value));
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
} else {
|
||||
__ movq(rcx, value, RelocInfo::NONE);
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__ movq(rcx, value, RelocInfo::NONE);
|
||||
__ movq(FieldOperand(result, total_offset), rcx);
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user