Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 669061: First take on custom call generators. (Closed)
Patch Set: Ultimate version Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 29 matching lines...) Expand all
40 // MacroAssembler implementation. 40 // MacroAssembler implementation.
41 41
42 MacroAssembler::MacroAssembler(void* buffer, int size) 42 MacroAssembler::MacroAssembler(void* buffer, int size)
43 : Assembler(buffer, size), 43 : Assembler(buffer, size),
44 generating_stub_(false), 44 generating_stub_(false),
45 allow_stub_calls_(true), 45 allow_stub_calls_(true),
46 code_object_(Heap::undefined_value()) { 46 code_object_(Heap::undefined_value()) {
47 } 47 }
48 48
49 49
50 static void RecordWriteHelper(MacroAssembler* masm, 50 void MacroAssembler::RecordWriteHelper(Register object,
51 Register object, 51 Register addr,
52 Register addr, 52 Register scratch) {
53 Register scratch) {
54 Label fast; 53 Label fast;
55 54
56 // Compute the page start address from the heap object pointer, and reuse 55 // Compute the page start address from the heap object pointer, and reuse
57 // the 'object' register for it. 56 // the 'object' register for it.
58 masm->and_(object, ~Page::kPageAlignmentMask); 57 and_(object, ~Page::kPageAlignmentMask);
59 Register page_start = object; 58 Register page_start = object;
60 59
61 // Compute the bit addr in the remembered set/index of the pointer in the 60 // Compute the bit addr in the remembered set/index of the pointer in the
62 // page. Reuse 'addr' as pointer_offset. 61 // page. Reuse 'addr' as pointer_offset.
63 masm->sub(addr, Operand(page_start)); 62 sub(addr, Operand(page_start));
64 masm->shr(addr, kObjectAlignmentBits); 63 shr(addr, kObjectAlignmentBits);
65 Register pointer_offset = addr; 64 Register pointer_offset = addr;
66 65
67 // If the bit offset lies beyond the normal remembered set range, it is in 66 // If the bit offset lies beyond the normal remembered set range, it is in
68 // the extra remembered set area of a large object. 67 // the extra remembered set area of a large object.
69 masm->cmp(pointer_offset, Page::kPageSize / kPointerSize); 68 cmp(pointer_offset, Page::kPageSize / kPointerSize);
70 masm->j(less, &fast); 69 j(less, &fast);
71 70
72 // Adjust 'page_start' so that addressing using 'pointer_offset' hits the 71 // Adjust 'page_start' so that addressing using 'pointer_offset' hits the
73 // extra remembered set after the large object. 72 // extra remembered set after the large object.
74 73
75 // Find the length of the large object (FixedArray). 74 // Find the length of the large object (FixedArray).
76 masm->mov(scratch, Operand(page_start, Page::kObjectStartOffset 75 mov(scratch, Operand(page_start, Page::kObjectStartOffset
77 + FixedArray::kLengthOffset)); 76 + FixedArray::kLengthOffset));
78 Register array_length = scratch; 77 Register array_length = scratch;
79 78
80 // Extra remembered set starts right after the large object (a FixedArray), at 79 // Extra remembered set starts right after the large object (a FixedArray), at
81 // page_start + kObjectStartOffset + objectSize 80 // page_start + kObjectStartOffset + objectSize
82 // where objectSize is FixedArray::kHeaderSize + kPointerSize * array_length. 81 // where objectSize is FixedArray::kHeaderSize + kPointerSize * array_length.
83 // Add the delta between the end of the normal RSet and the start of the 82 // Add the delta between the end of the normal RSet and the start of the
84 // extra RSet to 'page_start', so that addressing the bit using 83 // extra RSet to 'page_start', so that addressing the bit using
85 // 'pointer_offset' hits the extra RSet words. 84 // 'pointer_offset' hits the extra RSet words.
86 masm->lea(page_start, 85 lea(page_start,
87 Operand(page_start, array_length, times_pointer_size, 86 Operand(page_start, array_length, times_pointer_size,
88 Page::kObjectStartOffset + FixedArray::kHeaderSize 87 Page::kObjectStartOffset + FixedArray::kHeaderSize
89 - Page::kRSetEndOffset)); 88 - Page::kRSetEndOffset));
90 89
91 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction 90 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction
92 // to limit code size. We should probably evaluate this decision by 91 // to limit code size. We should probably evaluate this decision by
93 // measuring the performance of an equivalent implementation using 92 // measuring the performance of an equivalent implementation using
94 // "simpler" instructions 93 // "simpler" instructions
95 masm->bind(&fast); 94 bind(&fast);
96 masm->bts(Operand(page_start, Page::kRSetOffset), pointer_offset); 95 bts(Operand(page_start, Page::kRSetOffset), pointer_offset);
97 } 96 }
98 97
99 98
100 class RecordWriteStub : public CodeStub { 99 void MacroAssembler::InNewSpace(Register object,
101 public: 100 Register scratch,
102 RecordWriteStub(Register object, Register addr, Register scratch) 101 Condition cc,
103 : object_(object), addr_(addr), scratch_(scratch) { } 102 Label* branch) {
104 103 if (Serializer::enabled()) {
105 void Generate(MacroAssembler* masm); 104 // Can't do arithmetic on external references if it might get serialized.
106 105 mov(scratch, Operand(object));
107 private: 106 // The mask isn't really an address. We load it as an external reference in
108 Register object_; 107 // case the size of the new space is different between the snapshot maker
109 Register addr_; 108 // and the running system.
110 Register scratch_; 109 and_(Operand(scratch), Immediate(ExternalReference::new_space_mask()));
111 110 cmp(Operand(scratch), Immediate(ExternalReference::new_space_start()));
112 #ifdef DEBUG 111 j(cc, branch);
113 void Print() { 112 } else {
114 PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n", 113 int32_t new_space_start = reinterpret_cast<int32_t>(
115 object_.code(), addr_.code(), scratch_.code()); 114 ExternalReference::new_space_start().address());
115 lea(scratch, Operand(object, -new_space_start));
116 and_(scratch, Heap::NewSpaceMask());
117 j(cc, branch);
116 } 118 }
117 #endif
118
119 // Minor key encoding in 12 bits of three registers (object, address and
120 // scratch) OOOOAAAASSSS.
121 class ScratchBits: public BitField<uint32_t, 0, 4> {};
122 class AddressBits: public BitField<uint32_t, 4, 4> {};
123 class ObjectBits: public BitField<uint32_t, 8, 4> {};
124
125 Major MajorKey() { return RecordWrite; }
126
127 int MinorKey() {
128 // Encode the registers.
129 return ObjectBits::encode(object_.code()) |
130 AddressBits::encode(addr_.code()) |
131 ScratchBits::encode(scratch_.code());
132 }
133 };
134
135
136 void RecordWriteStub::Generate(MacroAssembler* masm) {
137 RecordWriteHelper(masm, object_, addr_, scratch_);
138 masm->ret(0);
139 } 119 }
140 120
141 121
142 // Set the remembered set bit for [object+offset]. 122 // Set the remembered set bit for [object+offset].
143 // object is the object being stored into, value is the object being stored. 123 // object is the object being stored into, value is the object being stored.
144 // If offset is zero, then the scratch register contains the array index into 124 // If offset is zero, then the scratch register contains the array index into
145 // the elements array represented as a Smi. 125 // the elements array represented as a Smi.
146 // All registers are clobbered by the operation. 126 // All registers are clobbered by the operation.
147 void MacroAssembler::RecordWrite(Register object, int offset, 127 void MacroAssembler::RecordWrite(Register object, int offset,
148 Register value, Register scratch) { 128 Register value, Register scratch) {
149 // The compiled code assumes that record write doesn't change the 129 // The compiled code assumes that record write doesn't change the
150 // context register, so we check that none of the clobbered 130 // context register, so we check that none of the clobbered
151 // registers are esi. 131 // registers are esi.
152 ASSERT(!object.is(esi) && !value.is(esi) && !scratch.is(esi)); 132 ASSERT(!object.is(esi) && !value.is(esi) && !scratch.is(esi));
153 133
154 // First, check if a remembered set write is even needed. The tests below 134 // First, check if a remembered set write is even needed. The tests below
155 // catch stores of Smis and stores into young gen (which does not have space 135 // catch stores of Smis and stores into young gen (which does not have space
156 // for the remembered set bits. 136 // for the remembered set bits.
157 Label done; 137 Label done;
158 138
159 // Skip barrier if writing a smi. 139 // Skip barrier if writing a smi.
160 ASSERT_EQ(0, kSmiTag); 140 ASSERT_EQ(0, kSmiTag);
161 test(value, Immediate(kSmiTagMask)); 141 test(value, Immediate(kSmiTagMask));
162 j(zero, &done); 142 j(zero, &done);
163 143
164 if (Serializer::enabled()) { 144 InNewSpace(object, value, equal, &done);
165 // Can't do arithmetic on external references if it might get serialized.
166 mov(value, Operand(object));
167 // The mask isn't really an address. We load it as an external reference in
168 // case the size of the new space is different between the snapshot maker
169 // and the running system.
170 and_(Operand(value), Immediate(ExternalReference::new_space_mask()));
171 cmp(Operand(value), Immediate(ExternalReference::new_space_start()));
172 j(equal, &done);
173 } else {
174 int32_t new_space_start = reinterpret_cast<int32_t>(
175 ExternalReference::new_space_start().address());
176 lea(value, Operand(object, -new_space_start));
177 and_(value, Heap::NewSpaceMask());
178 j(equal, &done);
179 }
180 145
181 if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) { 146 if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) {
182 // Compute the bit offset in the remembered set, leave it in 'value'. 147 // Compute the bit offset in the remembered set, leave it in 'value'.
183 lea(value, Operand(object, offset)); 148 lea(value, Operand(object, offset));
184 and_(value, Page::kPageAlignmentMask); 149 and_(value, Page::kPageAlignmentMask);
185 shr(value, kPointerSizeLog2); 150 shr(value, kPointerSizeLog2);
186 151
187 // Compute the page address from the heap object pointer, leave it in 152 // Compute the page address from the heap object pointer, leave it in
188 // 'object'. 153 // 'object'.
189 and_(object, ~Page::kPageAlignmentMask); 154 and_(object, ~Page::kPageAlignmentMask);
(...skipping 12 matching lines...) Expand all
202 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 167 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
203 // into an array of words. 168 // into an array of words.
204 ASSERT_EQ(1, kSmiTagSize); 169 ASSERT_EQ(1, kSmiTagSize);
205 ASSERT_EQ(0, kSmiTag); 170 ASSERT_EQ(0, kSmiTag);
206 lea(dst, Operand(object, dst, times_half_pointer_size, 171 lea(dst, Operand(object, dst, times_half_pointer_size,
207 FixedArray::kHeaderSize - kHeapObjectTag)); 172 FixedArray::kHeaderSize - kHeapObjectTag));
208 } 173 }
209 // If we are already generating a shared stub, not inlining the 174 // If we are already generating a shared stub, not inlining the
210 // record write code isn't going to save us any memory. 175 // record write code isn't going to save us any memory.
211 if (generating_stub()) { 176 if (generating_stub()) {
212 RecordWriteHelper(this, object, dst, value); 177 RecordWriteHelper(object, dst, value);
213 } else { 178 } else {
214 RecordWriteStub stub(object, dst, value); 179 RecordWriteStub stub(object, dst, value);
215 CallStub(&stub); 180 CallStub(&stub);
216 } 181 }
217 } 182 }
218 183
219 bind(&done); 184 bind(&done);
220 185
221 // Clobber all input registers when running with the debug-code flag 186 // Clobber all input registers when running with the debug-code flag
222 // turned on to provoke errors. 187 // turned on to provoke errors.
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 // Indicate that code has changed. 1644 // Indicate that code has changed.
1680 CPU::FlushICache(address_, size_); 1645 CPU::FlushICache(address_, size_);
1681 1646
1682 // Check that the code was patched as expected. 1647 // Check that the code was patched as expected.
1683 ASSERT(masm_.pc_ == address_ + size_); 1648 ASSERT(masm_.pc_ == address_ + size_);
1684 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 1649 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
1685 } 1650 }
1686 1651
1687 1652
1688 } } // namespace v8::internal 1653 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698