Version 3.9.8
Fixed memory leak and missing #include in StartupDataDecompressor (issue 1960).
Renamed static methods to avoid shadowing virtual methods and fix Clang C++11 compile error.
Fixed sequence of element access in array builtins (issue 1790).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@10776 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 538645a..3f00354 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4259,26 +4259,35 @@
__ Assert(equal, "Unexpected object literal boilerplate");
}
+ // Only elements backing stores for non-COW arrays need to be copied.
+ Handle<FixedArrayBase> elements(object->elements());
+ bool has_elements = elements->length() > 0 &&
+ elements->map() != isolate()->heap()->fixed_cow_array_map();
+
// Increase the offset so that subsequent objects end up right after
- // this one.
- int current_offset = *offset;
- int size = object->map()->instance_size();
- *offset += size;
+ // this object and its backing store.
+ int object_offset = *offset;
+ int object_size = object->map()->instance_size();
+ int elements_offset = *offset + object_size;
+ int elements_size = has_elements ? elements->Size() : 0;
+ *offset += object_size + elements_size;
// Copy object header.
ASSERT(object->properties()->length() == 0);
- ASSERT(object->elements()->length() == 0 ||
- object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
int inobject_properties = object->map()->inobject_properties();
- int header_size = size - inobject_properties * kPointerSize;
+ int header_size = object_size - inobject_properties * kPointerSize;
for (int i = 0; i < header_size; i += kPointerSize) {
- __ mov(ecx, FieldOperand(source, i));
- __ mov(FieldOperand(result, current_offset + i), ecx);
+ if (has_elements && i == JSObject::kElementsOffset) {
+ __ lea(ecx, Operand(result, elements_offset));
+ } else {
+ __ mov(ecx, FieldOperand(source, i));
+ }
+ __ mov(FieldOperand(result, object_offset + i), ecx);
}
// Copy in-object properties.
for (int i = 0; i < inobject_properties; i++) {
- int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
+ int total_offset = object_offset + object->GetInObjectPropertyOffset(i);
Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -4293,10 +4302,40 @@
__ mov(FieldOperand(result, total_offset), Immediate(value));
}
}
+
+ // Copy elements backing store header.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ if (has_elements) {
+ __ 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);
+ } else {
+ __ mov(FieldOperand(result, total_offset), Immediate(value));
+ }
+ }
}
-void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
+void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
int size = instr->hydrogen()->total_size();
@@ -4318,7 +4357,7 @@
}
-void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
+void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
Handle<FixedArray> literals(instr->environment()->closure()->literals());
Handle<FixedArray> constant_properties =