| 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 5413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5424 __ push(r0); | 5424 __ push(r0); |
| 5425 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 5425 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); |
| 5426 __ StoreToSafepointRegisterSlot(r0, result); | 5426 __ StoreToSafepointRegisterSlot(r0, result); |
| 5427 } | 5427 } |
| 5428 | 5428 |
| 5429 | 5429 |
| 5430 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 5430 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| 5431 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5431 Handle<FixedArray> literals(instr->environment()->closure()->literals()); |
| 5432 ElementsKind boilerplate_elements_kind = | 5432 ElementsKind boilerplate_elements_kind = |
| 5433 instr->hydrogen()->boilerplate_elements_kind(); | 5433 instr->hydrogen()->boilerplate_elements_kind(); |
| 5434 AllocationSiteMode allocation_site_mode = |
| 5435 instr->hydrogen()->allocation_site_mode(); |
| 5434 | 5436 |
| 5435 // Deopt if the array literal boilerplate ElementsKind is of a type different | 5437 // Deopt if the array literal boilerplate ElementsKind is of a type different |
| 5436 // than the expected one. The check isn't necessary if the boilerplate has | 5438 // than the expected one. The check isn't necessary if the boilerplate has |
| 5437 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 5439 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
| 5438 if (CanTransitionToMoreGeneralFastElementsKind( | 5440 if (CanTransitionToMoreGeneralFastElementsKind( |
| 5439 boilerplate_elements_kind, true)) { | 5441 boilerplate_elements_kind, true)) { |
| 5440 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object()); | 5442 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object()); |
| 5441 // Load map into r2. | 5443 // Load map into r2. |
| 5442 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 5444 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| 5443 // Load the map's "bit field 2". | 5445 // Load the map's "bit field 2". |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5455 // Pass an empty fixed array. | 5457 // Pass an empty fixed array. |
| 5456 __ mov(r1, Operand(isolate()->factory()->empty_fixed_array())); | 5458 __ mov(r1, Operand(isolate()->factory()->empty_fixed_array())); |
| 5457 __ Push(r3, r2, r1); | 5459 __ Push(r3, r2, r1); |
| 5458 | 5460 |
| 5459 // Pick the right runtime function or stub to call. | 5461 // Pick the right runtime function or stub to call. |
| 5460 int length = instr->hydrogen()->length(); | 5462 int length = instr->hydrogen()->length(); |
| 5461 if (instr->hydrogen()->IsCopyOnWrite()) { | 5463 if (instr->hydrogen()->IsCopyOnWrite()) { |
| 5462 ASSERT(instr->hydrogen()->depth() == 1); | 5464 ASSERT(instr->hydrogen()->depth() == 1); |
| 5463 FastCloneShallowArrayStub::Mode mode = | 5465 FastCloneShallowArrayStub::Mode mode = |
| 5464 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; | 5466 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; |
| 5465 FastCloneShallowArrayStub stub(mode, length); | 5467 FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length); |
| 5466 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 5468 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 5467 } else if (instr->hydrogen()->depth() > 1) { | 5469 } else if (instr->hydrogen()->depth() > 1) { |
| 5468 CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); | 5470 CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); |
| 5469 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 5471 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 5470 CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); | 5472 CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); |
| 5471 } else { | 5473 } else { |
| 5472 FastCloneShallowArrayStub::Mode mode = | 5474 FastCloneShallowArrayStub::Mode mode = |
| 5473 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 5475 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |
| 5474 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 5476 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
| 5475 : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 5477 : FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 5476 FastCloneShallowArrayStub stub(mode, length); | 5478 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); |
| 5477 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 5479 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 5478 } | 5480 } |
| 5479 } | 5481 } |
| 5480 | 5482 |
| 5481 | 5483 |
| 5482 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, | 5484 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| 5483 Register result, | 5485 Register result, |
| 5484 Register source, | 5486 Register source, |
| 5485 int* offset) { | 5487 int* offset, |
| 5488 AllocationSiteMode mode) { |
| 5486 ASSERT(!source.is(r2)); | 5489 ASSERT(!source.is(r2)); |
| 5487 ASSERT(!result.is(r2)); | 5490 ASSERT(!result.is(r2)); |
| 5488 | 5491 |
| 5492 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && |
| 5493 object->map()->CanTrackAllocationSite(); |
| 5494 |
| 5489 // Only elements backing stores for non-COW arrays need to be copied. | 5495 // Only elements backing stores for non-COW arrays need to be copied. |
| 5490 Handle<FixedArrayBase> elements(object->elements()); | 5496 Handle<FixedArrayBase> elements(object->elements()); |
| 5491 bool has_elements = elements->length() > 0 && | 5497 bool has_elements = elements->length() > 0 && |
| 5492 elements->map() != isolate()->heap()->fixed_cow_array_map(); | 5498 elements->map() != isolate()->heap()->fixed_cow_array_map(); |
| 5493 | 5499 |
| 5494 // Increase the offset so that subsequent objects end up right after | 5500 // Increase the offset so that subsequent objects end up right after |
| 5495 // this object and its backing store. | 5501 // this object and its backing store. |
| 5496 int object_offset = *offset; | 5502 int object_offset = *offset; |
| 5497 int object_size = object->map()->instance_size(); | 5503 int object_size = object->map()->instance_size(); |
| 5504 int elements_size = has_elements ? elements->Size() : 0; |
| 5498 int elements_offset = *offset + object_size; | 5505 int elements_offset = *offset + object_size; |
| 5499 int elements_size = has_elements ? elements->Size() : 0; | 5506 if (create_allocation_site_info) { |
| 5507 elements_offset += AllocationSiteInfo::kSize; |
| 5508 *offset += AllocationSiteInfo::kSize; |
| 5509 } |
| 5510 |
| 5500 *offset += object_size + elements_size; | 5511 *offset += object_size + elements_size; |
| 5501 | 5512 |
| 5502 // Copy object header. | 5513 // Copy object header. |
| 5503 ASSERT(object->properties()->length() == 0); | 5514 ASSERT(object->properties()->length() == 0); |
| 5504 int inobject_properties = object->map()->inobject_properties(); | 5515 int inobject_properties = object->map()->inobject_properties(); |
| 5505 int header_size = object_size - inobject_properties * kPointerSize; | 5516 int header_size = object_size - inobject_properties * kPointerSize; |
| 5506 for (int i = 0; i < header_size; i += kPointerSize) { | 5517 for (int i = 0; i < header_size; i += kPointerSize) { |
| 5507 if (has_elements && i == JSObject::kElementsOffset) { | 5518 if (has_elements && i == JSObject::kElementsOffset) { |
| 5508 __ add(r2, result, Operand(elements_offset)); | 5519 __ add(r2, result, Operand(elements_offset)); |
| 5509 } else { | 5520 } else { |
| 5510 __ ldr(r2, FieldMemOperand(source, i)); | 5521 __ ldr(r2, FieldMemOperand(source, i)); |
| 5511 } | 5522 } |
| 5512 __ str(r2, FieldMemOperand(result, object_offset + i)); | 5523 __ str(r2, FieldMemOperand(result, object_offset + i)); |
| 5513 } | 5524 } |
| 5514 | 5525 |
| 5515 // Copy in-object properties. | 5526 // Copy in-object properties. |
| 5516 for (int i = 0; i < inobject_properties; i++) { | 5527 for (int i = 0; i < inobject_properties; i++) { |
| 5517 int total_offset = object_offset + object->GetInObjectPropertyOffset(i); | 5528 int total_offset = object_offset + object->GetInObjectPropertyOffset(i); |
| 5518 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 5529 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); |
| 5519 if (value->IsJSObject()) { | 5530 if (value->IsJSObject()) { |
| 5520 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5531 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 5521 __ add(r2, result, Operand(*offset)); | 5532 __ add(r2, result, Operand(*offset)); |
| 5522 __ str(r2, FieldMemOperand(result, total_offset)); | 5533 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5523 __ LoadHeapObject(source, value_object); | 5534 __ LoadHeapObject(source, value_object); |
| 5524 EmitDeepCopy(value_object, result, source, offset); | 5535 EmitDeepCopy(value_object, result, source, offset, |
| 5536 DONT_TRACK_ALLOCATION_SITE); |
| 5525 } else if (value->IsHeapObject()) { | 5537 } else if (value->IsHeapObject()) { |
| 5526 __ LoadHeapObject(r2, Handle<HeapObject>::cast(value)); | 5538 __ LoadHeapObject(r2, Handle<HeapObject>::cast(value)); |
| 5527 __ str(r2, FieldMemOperand(result, total_offset)); | 5539 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5528 } else { | 5540 } else { |
| 5529 __ mov(r2, Operand(value)); | 5541 __ mov(r2, Operand(value)); |
| 5530 __ str(r2, FieldMemOperand(result, total_offset)); | 5542 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5531 } | 5543 } |
| 5532 } | 5544 } |
| 5533 | 5545 |
| 5546 // Build Allocation Site Info if desired |
| 5547 if (create_allocation_site_info) { |
| 5548 __ mov(r2, Operand(Handle<Map>(isolate()->heap()-> |
| 5549 allocation_site_info_map()))); |
| 5550 __ str(r2, FieldMemOperand(result, object_size)); |
| 5551 __ str(source, FieldMemOperand(result, object_size + kPointerSize)); |
| 5552 } |
| 5553 |
| 5534 if (has_elements) { | 5554 if (has_elements) { |
| 5535 // Copy elements backing store header. | 5555 // Copy elements backing store header. |
| 5536 __ LoadHeapObject(source, elements); | 5556 __ LoadHeapObject(source, elements); |
| 5537 for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { | 5557 for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { |
| 5538 __ ldr(r2, FieldMemOperand(source, i)); | 5558 __ ldr(r2, FieldMemOperand(source, i)); |
| 5539 __ str(r2, FieldMemOperand(result, elements_offset + i)); | 5559 __ str(r2, FieldMemOperand(result, elements_offset + i)); |
| 5540 } | 5560 } |
| 5541 | 5561 |
| 5542 // Copy elements backing store content. | 5562 // Copy elements backing store content. |
| 5543 int elements_length = has_elements ? elements->length() : 0; | 5563 int elements_length = has_elements ? elements->length() : 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5559 } else if (elements->IsFixedArray()) { | 5579 } else if (elements->IsFixedArray()) { |
| 5560 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 5580 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 5561 for (int i = 0; i < elements_length; i++) { | 5581 for (int i = 0; i < elements_length; i++) { |
| 5562 int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); | 5582 int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); |
| 5563 Handle<Object> value(fast_elements->get(i)); | 5583 Handle<Object> value(fast_elements->get(i)); |
| 5564 if (value->IsJSObject()) { | 5584 if (value->IsJSObject()) { |
| 5565 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5585 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 5566 __ add(r2, result, Operand(*offset)); | 5586 __ add(r2, result, Operand(*offset)); |
| 5567 __ str(r2, FieldMemOperand(result, total_offset)); | 5587 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5568 __ LoadHeapObject(source, value_object); | 5588 __ LoadHeapObject(source, value_object); |
| 5569 EmitDeepCopy(value_object, result, source, offset); | 5589 EmitDeepCopy(value_object, result, source, offset, |
| 5590 DONT_TRACK_ALLOCATION_SITE); |
| 5570 } else if (value->IsHeapObject()) { | 5591 } else if (value->IsHeapObject()) { |
| 5571 __ LoadHeapObject(r2, Handle<HeapObject>::cast(value)); | 5592 __ LoadHeapObject(r2, Handle<HeapObject>::cast(value)); |
| 5572 __ str(r2, FieldMemOperand(result, total_offset)); | 5593 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5573 } else { | 5594 } else { |
| 5574 __ mov(r2, Operand(value)); | 5595 __ mov(r2, Operand(value)); |
| 5575 __ str(r2, FieldMemOperand(result, total_offset)); | 5596 __ str(r2, FieldMemOperand(result, total_offset)); |
| 5576 } | 5597 } |
| 5577 } | 5598 } |
| 5578 } else { | 5599 } else { |
| 5579 UNREACHABLE(); | 5600 UNREACHABLE(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5610 __ jmp(&allocated); | 5631 __ jmp(&allocated); |
| 5611 | 5632 |
| 5612 __ bind(&runtime_allocate); | 5633 __ bind(&runtime_allocate); |
| 5613 __ mov(r0, Operand(Smi::FromInt(size))); | 5634 __ mov(r0, Operand(Smi::FromInt(size))); |
| 5614 __ push(r0); | 5635 __ push(r0); |
| 5615 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 5636 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |
| 5616 | 5637 |
| 5617 __ bind(&allocated); | 5638 __ bind(&allocated); |
| 5618 int offset = 0; | 5639 int offset = 0; |
| 5619 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); | 5640 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); |
| 5620 EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset); | 5641 EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset, |
| 5642 instr->hydrogen()->allocation_site_mode()); |
| 5621 ASSERT_EQ(size, offset); | 5643 ASSERT_EQ(size, offset); |
| 5622 } | 5644 } |
| 5623 | 5645 |
| 5624 | 5646 |
| 5625 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 5647 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| 5626 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5648 Handle<FixedArray> literals(instr->environment()->closure()->literals()); |
| 5627 Handle<FixedArray> constant_properties = | 5649 Handle<FixedArray> constant_properties = |
| 5628 instr->hydrogen()->constant_properties(); | 5650 instr->hydrogen()->constant_properties(); |
| 5629 | 5651 |
| 5630 // Set up the parameters to the stub/runtime call. | 5652 // Set up the parameters to the stub/runtime call. |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6084 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6106 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 6085 __ ldr(result, FieldMemOperand(scratch, | 6107 __ ldr(result, FieldMemOperand(scratch, |
| 6086 FixedArray::kHeaderSize - kPointerSize)); | 6108 FixedArray::kHeaderSize - kPointerSize)); |
| 6087 __ bind(&done); | 6109 __ bind(&done); |
| 6088 } | 6110 } |
| 6089 | 6111 |
| 6090 | 6112 |
| 6091 #undef __ | 6113 #undef __ |
| 6092 | 6114 |
| 6093 } } // namespace v8::internal | 6115 } } // namespace v8::internal |
| OLD | NEW |