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

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

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: 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 | Annotate | Revision Log
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 // The mask isn't really an address. We load it as an external reference in
178 // case the size of the new space is different between the snapshot maker
179 // and the running system.
180 and_(Operand(value), Immediate(ExternalReference::new_space_mask()));
181 j(equal, &done);
182 }
183 145
184 if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) { 146 if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) {
185 // 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'.
186 lea(value, Operand(object, offset)); 148 lea(value, Operand(object, offset));
187 and_(value, Page::kPageAlignmentMask); 149 and_(value, Page::kPageAlignmentMask);
188 shr(value, kPointerSizeLog2); 150 shr(value, kPointerSizeLog2);
189 151
190 // 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
191 // 'object'. 153 // 'object'.
192 and_(object, ~Page::kPageAlignmentMask); 154 and_(object, ~Page::kPageAlignmentMask);
(...skipping 12 matching lines...) Expand all
205 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 167 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
206 // into an array of words. 168 // into an array of words.
207 ASSERT_EQ(1, kSmiTagSize); 169 ASSERT_EQ(1, kSmiTagSize);
208 ASSERT_EQ(0, kSmiTag); 170 ASSERT_EQ(0, kSmiTag);
209 lea(dst, Operand(object, dst, times_half_pointer_size, 171 lea(dst, Operand(object, dst, times_half_pointer_size,
210 FixedArray::kHeaderSize - kHeapObjectTag)); 172 FixedArray::kHeaderSize - kHeapObjectTag));
211 } 173 }
212 // If we are already generating a shared stub, not inlining the 174 // If we are already generating a shared stub, not inlining the
213 // record write code isn't going to save us any memory. 175 // record write code isn't going to save us any memory.
214 if (generating_stub()) { 176 if (generating_stub()) {
215 RecordWriteHelper(this, object, dst, value); 177 RecordWriteHelper(object, dst, value);
216 } else { 178 } else {
217 RecordWriteStub stub(object, dst, value); 179 RecordWriteStub stub(object, dst, value);
218 CallStub(&stub); 180 CallStub(&stub);
219 } 181 }
220 } 182 }
221 183
222 bind(&done); 184 bind(&done);
223 185
224 // Clobber all input registers when running with the debug-code flag 186 // Clobber all input registers when running with the debug-code flag
225 // turned on to provoke errors. 187 // turned on to provoke errors.
226 if (FLAG_debug_code) { 188 if (FLAG_debug_code) {
227 mov(object, Immediate(bit_cast<int32_t>(kZapValue))); 189 mov(object, Immediate(BitCast<int32_t>(kZapValue)));
228 mov(value, Immediate(bit_cast<int32_t>(kZapValue))); 190 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
229 mov(scratch, Immediate(bit_cast<int32_t>(kZapValue))); 191 mov(scratch, Immediate(BitCast<int32_t>(kZapValue)));
230 } 192 }
231 } 193 }
232 194
233 195
234 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { 196 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) {
235 cmp(esp, 197 cmp(esp,
236 Operand::StaticVariable(ExternalReference::address_of_stack_limit())); 198 Operand::StaticVariable(ExternalReference::address_of_stack_limit()));
237 j(below, on_stack_overflow); 199 j(below, on_stack_overflow);
238 } 200 }
239 201
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } else { 344 } else {
383 fucompp(); 345 fucompp();
384 push(eax); 346 push(eax);
385 fnstsw_ax(); 347 fnstsw_ax();
386 sahf(); 348 sahf();
387 pop(eax); 349 pop(eax);
388 } 350 }
389 } 351 }
390 352
391 353
392 void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) { 354 void MacroAssembler::AbortIfNotNumber(Register object) {
393 Label ok; 355 Label ok;
394 test(object, Immediate(kSmiTagMask)); 356 test(object, Immediate(kSmiTagMask));
395 j(zero, &ok); 357 j(zero, &ok);
396 cmp(FieldOperand(object, HeapObject::kMapOffset), 358 cmp(FieldOperand(object, HeapObject::kMapOffset),
397 Factory::heap_number_map()); 359 Factory::heap_number_map());
398 Assert(equal, msg); 360 Assert(equal, "Operand not a number");
399 bind(&ok); 361 bind(&ok);
400 } 362 }
401 363
402 364
365 void MacroAssembler::AbortIfNotSmi(Register object) {
366 test(object, Immediate(kSmiTagMask));
367 Assert(equal, "Operand not a smi");
368 }
369
370
403 void MacroAssembler::EnterFrame(StackFrame::Type type) { 371 void MacroAssembler::EnterFrame(StackFrame::Type type) {
404 push(ebp); 372 push(ebp);
405 mov(ebp, Operand(esp)); 373 mov(ebp, Operand(esp));
406 push(esi); 374 push(esi);
407 push(Immediate(Smi::FromInt(type))); 375 push(Immediate(Smi::FromInt(type)));
408 push(Immediate(CodeObject())); 376 push(Immediate(CodeObject()));
409 if (FLAG_debug_code) { 377 if (FLAG_debug_code) {
410 cmp(Operand(esp, 0), Immediate(Factory::undefined_value())); 378 cmp(Operand(esp, 0), Immediate(Factory::undefined_value()));
411 Check(not_equal, "code object not properly patched"); 379 Check(not_equal, "code object not properly patched");
412 } 380 }
(...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0)))); 1546 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0))));
1579 CallRuntime(Runtime::kAbort, 2); 1547 CallRuntime(Runtime::kAbort, 2);
1580 // will not return here 1548 // will not return here
1581 int3(); 1549 int3();
1582 } 1550 }
1583 1551
1584 1552
1585 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 1553 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
1586 Register instance_type, 1554 Register instance_type,
1587 Register scratch, 1555 Register scratch,
1588 Label *failure) { 1556 Label* failure) {
1589 if (!scratch.is(instance_type)) { 1557 if (!scratch.is(instance_type)) {
1590 mov(scratch, instance_type); 1558 mov(scratch, instance_type);
1591 } 1559 }
1592 and_(scratch, 1560 and_(scratch,
1593 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 1561 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
1594 cmp(scratch, kStringTag | kSeqStringTag | kAsciiStringTag); 1562 cmp(scratch, kStringTag | kSeqStringTag | kAsciiStringTag);
1595 j(not_equal, failure); 1563 j(not_equal, failure);
1596 } 1564 }
1597 1565
1598 1566
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 // Indicate that code has changed. 1644 // Indicate that code has changed.
1677 CPU::FlushICache(address_, size_); 1645 CPU::FlushICache(address_, size_);
1678 1646
1679 // Check that the code was patched as expected. 1647 // Check that the code was patched as expected.
1680 ASSERT(masm_.pc_ == address_ + size_); 1648 ASSERT(masm_.pc_ == address_ + size_);
1681 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 1649 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
1682 } 1650 }
1683 1651
1684 1652
1685 } } // namespace v8::internal 1653 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698