OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4253 int* offset) { | 4253 int* offset) { |
4254 ASSERT(!source.is(ecx)); | 4254 ASSERT(!source.is(ecx)); |
4255 ASSERT(!result.is(ecx)); | 4255 ASSERT(!result.is(ecx)); |
4256 | 4256 |
4257 if (FLAG_debug_code) { | 4257 if (FLAG_debug_code) { |
4258 __ LoadHeapObject(ecx, object); | 4258 __ LoadHeapObject(ecx, object); |
4259 __ cmp(source, ecx); | 4259 __ cmp(source, ecx); |
4260 __ Assert(equal, "Unexpected object literal boilerplate"); | 4260 __ Assert(equal, "Unexpected object literal boilerplate"); |
4261 } | 4261 } |
4262 | 4262 |
| 4263 // Only elements backing stores for non-cow arrays need to be copied. |
| 4264 Handle<FixedArrayBase> elements(object->elements()); |
| 4265 bool has_elements = elements->length() > 0 && |
| 4266 elements->map() != isolate()->heap()->fixed_cow_array_map(); |
| 4267 |
4263 // Increase the offset so that subsequent objects end up right after | 4268 // Increase the offset so that subsequent objects end up right after |
4264 // this one. | 4269 // this object and its backing store. |
4265 int current_offset = *offset; | 4270 int object_offset = *offset; |
4266 int size = object->map()->instance_size(); | 4271 int object_size = object->map()->instance_size(); |
4267 *offset += size; | 4272 int elements_offset = *offset + object_size; |
| 4273 int elements_size = has_elements ? elements->Size() : 0; |
| 4274 *offset += object_size + elements_size; |
4268 | 4275 |
4269 // Copy object header. | 4276 // Copy object header. |
4270 ASSERT(object->properties()->length() == 0); | 4277 ASSERT(object->properties()->length() == 0); |
4271 ASSERT(object->elements()->length() == 0 || | |
4272 object->elements()->map() == isolate()->heap()->fixed_cow_array_map()); | |
4273 int inobject_properties = object->map()->inobject_properties(); | 4278 int inobject_properties = object->map()->inobject_properties(); |
4274 int header_size = size - inobject_properties * kPointerSize; | 4279 int header_size = object_size - inobject_properties * kPointerSize; |
4275 for (int i = 0; i < header_size; i += kPointerSize) { | 4280 for (int i = 0; i < header_size; i += kPointerSize) { |
4276 __ mov(ecx, FieldOperand(source, i)); | 4281 if (has_elements && i == JSObject::kElementsOffset) { |
4277 __ mov(FieldOperand(result, current_offset + i), ecx); | 4282 __ lea(ecx, Operand(result, elements_offset)); |
| 4283 __ mov(FieldOperand(result, object_offset + i), ecx); |
| 4284 } else { |
| 4285 __ mov(ecx, FieldOperand(source, i)); |
| 4286 __ mov(FieldOperand(result, object_offset + i), ecx); |
| 4287 } |
4278 } | 4288 } |
4279 | 4289 |
4280 // Copy in-object properties. | 4290 // Copy in-object properties. |
4281 for (int i = 0; i < inobject_properties; i++) { | 4291 for (int i = 0; i < inobject_properties; i++) { |
4282 int total_offset = current_offset + object->GetInObjectPropertyOffset(i); | 4292 int total_offset = object_offset + object->GetInObjectPropertyOffset(i); |
4283 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 4293 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); |
4284 if (value->IsJSObject()) { | 4294 if (value->IsJSObject()) { |
4285 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 4295 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
4286 __ lea(ecx, Operand(result, *offset)); | 4296 __ lea(ecx, Operand(result, *offset)); |
4287 __ mov(FieldOperand(result, total_offset), ecx); | 4297 __ mov(FieldOperand(result, total_offset), ecx); |
4288 __ LoadHeapObject(source, value_object); | 4298 __ LoadHeapObject(source, value_object); |
4289 EmitDeepCopy(value_object, result, source, offset); | 4299 EmitDeepCopy(value_object, result, source, offset); |
4290 } else if (value->IsHeapObject()) { | 4300 } else if (value->IsHeapObject()) { |
4291 __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); | 4301 __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); |
4292 __ mov(FieldOperand(result, total_offset), ecx); | 4302 __ mov(FieldOperand(result, total_offset), ecx); |
4293 } else { | 4303 } else { |
4294 __ mov(FieldOperand(result, total_offset), Immediate(value)); | 4304 __ mov(FieldOperand(result, total_offset), Immediate(value)); |
4295 } | 4305 } |
4296 } | 4306 } |
| 4307 |
| 4308 // Copy elements backing store header. |
| 4309 ASSERT(!has_elements || elements->IsFixedArray()); |
| 4310 if (has_elements) { |
| 4311 __ LoadHeapObject(source, elements); |
| 4312 for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { |
| 4313 __ mov(ecx, FieldOperand(source, i)); |
| 4314 __ mov(FieldOperand(result, elements_offset + i), ecx); |
| 4315 } |
| 4316 } |
| 4317 |
| 4318 // Copy elements backing store content. |
| 4319 ASSERT(!has_elements || elements->IsFixedArray()); |
| 4320 int elements_length = has_elements ? elements->length() : 0; |
| 4321 for (int i = 0; i < elements_length; i++) { |
| 4322 int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); |
| 4323 Handle<Object> value = JSObject::GetElement(object, i); |
| 4324 if (value->IsJSObject()) { |
| 4325 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 4326 __ lea(ecx, Operand(result, *offset)); |
| 4327 __ mov(FieldOperand(result, total_offset), ecx); |
| 4328 __ LoadHeapObject(source, value_object); |
| 4329 EmitDeepCopy(value_object, result, source, offset); |
| 4330 } else if (value->IsHeapObject()) { |
| 4331 __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); |
| 4332 __ mov(FieldOperand(result, total_offset), ecx); |
| 4333 } else { |
| 4334 __ mov(FieldOperand(result, total_offset), Immediate(value)); |
| 4335 } |
| 4336 } |
4297 } | 4337 } |
4298 | 4338 |
4299 | 4339 |
4300 void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { | 4340 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
4301 ASSERT(ToRegister(instr->context()).is(esi)); | 4341 ASSERT(ToRegister(instr->context()).is(esi)); |
4302 int size = instr->hydrogen()->total_size(); | 4342 int size = instr->hydrogen()->total_size(); |
4303 | 4343 |
4304 // Allocate all objects that are part of the literal in one big | 4344 // Allocate all objects that are part of the literal in one big |
4305 // allocation. This avoids multiple limit checks. | 4345 // allocation. This avoids multiple limit checks. |
4306 Label allocated, runtime_allocate; | 4346 Label allocated, runtime_allocate; |
4307 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); | 4347 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); |
4308 __ jmp(&allocated); | 4348 __ jmp(&allocated); |
4309 | 4349 |
4310 __ bind(&runtime_allocate); | 4350 __ bind(&runtime_allocate); |
4311 __ push(Immediate(Smi::FromInt(size))); | 4351 __ push(Immediate(Smi::FromInt(size))); |
4312 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 4352 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |
4313 | 4353 |
4314 __ bind(&allocated); | 4354 __ bind(&allocated); |
4315 int offset = 0; | 4355 int offset = 0; |
4316 __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); | 4356 __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); |
4317 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset); | 4357 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset); |
4318 ASSERT_EQ(size, offset); | 4358 ASSERT_EQ(size, offset); |
4319 } | 4359 } |
4320 | 4360 |
4321 | 4361 |
4322 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { | 4362 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
4323 ASSERT(ToRegister(instr->context()).is(esi)); | 4363 ASSERT(ToRegister(instr->context()).is(esi)); |
4324 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 4364 Handle<FixedArray> literals(instr->environment()->closure()->literals()); |
4325 Handle<FixedArray> constant_properties = | 4365 Handle<FixedArray> constant_properties = |
4326 instr->hydrogen()->constant_properties(); | 4366 instr->hydrogen()->constant_properties(); |
4327 | 4367 |
4328 // Set up the parameters to the stub/runtime call. | 4368 // Set up the parameters to the stub/runtime call. |
4329 __ PushHeapObject(literals); | 4369 __ PushHeapObject(literals); |
4330 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 4370 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
4331 __ push(Immediate(constant_properties)); | 4371 __ push(Immediate(constant_properties)); |
4332 int flags = instr->hydrogen()->fast_elements() | 4372 int flags = instr->hydrogen()->fast_elements() |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4689 this, pointers, Safepoint::kLazyDeopt); | 4729 this, pointers, Safepoint::kLazyDeopt); |
4690 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4730 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4691 } | 4731 } |
4692 | 4732 |
4693 | 4733 |
4694 #undef __ | 4734 #undef __ |
4695 | 4735 |
4696 } } // namespace v8::internal | 4736 } } // namespace v8::internal |
4697 | 4737 |
4698 #endif // V8_TARGET_ARCH_IA32 | 4738 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |