OLD | NEW |
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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 Register offset, | 245 Register offset, |
246 Register scratch) { | 246 Register scratch) { |
247 if (FLAG_debug_code) { | 247 if (FLAG_debug_code) { |
248 // Check that the object is not in new space. | 248 // Check that the object is not in new space. |
249 Label not_in_new_space; | 249 Label not_in_new_space; |
250 InNewSpace(object, scratch, ne, ¬_in_new_space); | 250 InNewSpace(object, scratch, ne, ¬_in_new_space); |
251 Abort("new-space object passed to RecordWriteHelper"); | 251 Abort("new-space object passed to RecordWriteHelper"); |
252 bind(¬_in_new_space); | 252 bind(¬_in_new_space); |
253 } | 253 } |
254 | 254 |
255 // This is how much we shift the remembered set bit offset to get the | 255 mov(ip, Operand(Page::kPageAlignmentMask)); // Load mask only once. |
256 // offset of the word in the remembered set. We divide by kBitsPerInt (32, | |
257 // shift right 5) and then multiply by kIntSize (4, shift left 2). | |
258 const int kRSetWordShift = 3; | |
259 | 256 |
260 Label fast; | 257 // Calculate region number. |
| 258 add(offset, object, Operand(offset)); // Add offset into the object. |
| 259 and_(offset, offset, Operand(ip)); // Offset into page of the object. |
| 260 mov(offset, Operand(offset, LSR, Page::kRegionSizeLog2)); |
261 | 261 |
262 // Compute the bit offset in the remembered set. | 262 // Calculate page address. |
263 // object: heap object pointer (with tag) | |
264 // offset: offset to store location from the object | |
265 mov(ip, Operand(Page::kPageAlignmentMask)); // load mask only once | |
266 and_(scratch, object, Operand(ip)); // offset into page of the object | |
267 add(offset, scratch, Operand(offset)); // add offset into the object | |
268 mov(offset, Operand(offset, LSR, kObjectAlignmentBits)); | |
269 | |
270 // Compute the page address from the heap object pointer. | |
271 // object: heap object pointer (with tag) | |
272 // offset: bit offset of store position in the remembered set | |
273 bic(object, object, Operand(ip)); | 263 bic(object, object, Operand(ip)); |
274 | 264 |
275 // If the bit offset lies beyond the normal remembered set range, it is in | 265 // Mark region dirty. |
276 // the extra remembered set area of a large object. | 266 ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
277 // object: page start | |
278 // offset: bit offset of store position in the remembered set | |
279 cmp(offset, Operand(Page::kPageSize / kPointerSize)); | |
280 b(lt, &fast); | |
281 | |
282 // Adjust the bit offset to be relative to the start of the extra | |
283 // remembered set and the start address to be the address of the extra | |
284 // remembered set. | |
285 sub(offset, offset, Operand(Page::kPageSize / kPointerSize)); | |
286 // Load the array length into 'scratch' and multiply by four to get the | |
287 // size in bytes of the elements. | |
288 ldr(scratch, MemOperand(object, Page::kObjectStartOffset | |
289 + FixedArray::kLengthOffset)); | |
290 mov(scratch, Operand(scratch, LSL, kObjectAlignmentBits)); | |
291 // Add the page header (including remembered set), array header, and array | |
292 // body size to the page address. | |
293 add(object, object, Operand(Page::kObjectStartOffset | |
294 + FixedArray::kHeaderSize)); | |
295 add(object, object, Operand(scratch)); | |
296 | |
297 bind(&fast); | |
298 // Get address of the rset word. | |
299 // object: start of the remembered set (page start for the fast case) | |
300 // offset: bit offset of store position in the remembered set | |
301 bic(scratch, offset, Operand(kBitsPerInt - 1)); // clear the bit offset | |
302 add(object, object, Operand(scratch, LSR, kRSetWordShift)); | |
303 // Get bit offset in the rset word. | |
304 // object: address of remembered set word | |
305 // offset: bit offset of store position | |
306 and_(offset, offset, Operand(kBitsPerInt - 1)); | |
307 | |
308 ldr(scratch, MemOperand(object)); | |
309 mov(ip, Operand(1)); | 267 mov(ip, Operand(1)); |
310 orr(scratch, scratch, Operand(ip, LSL, offset)); | 268 orr(scratch, scratch, Operand(ip, LSL, offset)); |
311 str(scratch, MemOperand(object)); | 269 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
312 } | 270 } |
313 | 271 |
314 | 272 |
315 void MacroAssembler::InNewSpace(Register object, | 273 void MacroAssembler::InNewSpace(Register object, |
316 Register scratch, | 274 Register scratch, |
317 Condition cc, | 275 Condition cc, |
318 Label* branch) { | 276 Label* branch) { |
319 ASSERT(cc == eq || cc == ne); | 277 ASSERT(cc == eq || cc == ne); |
320 and_(scratch, object, Operand(ExternalReference::new_space_mask())); | 278 and_(scratch, object, Operand(ExternalReference::new_space_mask())); |
321 cmp(scratch, Operand(ExternalReference::new_space_start())); | 279 cmp(scratch, Operand(ExternalReference::new_space_start())); |
322 b(cc, branch); | 280 b(cc, branch); |
323 } | 281 } |
324 | 282 |
325 | 283 |
326 // Will clobber 4 registers: object, offset, scratch, ip. The | 284 // Will clobber 4 registers: object, offset, scratch, ip. The |
327 // register 'object' contains a heap object pointer. The heap object | 285 // register 'object' contains a heap object pointer. The heap object |
328 // tag is shifted away. | 286 // tag is shifted away. |
329 void MacroAssembler::RecordWrite(Register object, Register offset, | 287 void MacroAssembler::RecordWrite(Register object, Register offset, |
330 Register scratch) { | 288 Register scratch) { |
331 // The compiled code assumes that record write doesn't change the | 289 // The compiled code assumes that record write doesn't change the |
332 // context register, so we check that none of the clobbered | 290 // context register, so we check that none of the clobbered |
333 // registers are cp. | 291 // registers are cp. |
334 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); | 292 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); |
335 | 293 |
336 Label done; | 294 Label done; |
337 | 295 |
338 // First, test that the object is not in the new space. We cannot set | 296 // First, test that the object is not in the new space. We cannot set |
339 // remembered set bits in the new space. | 297 // region marks for new space pages. |
340 InNewSpace(object, scratch, eq, &done); | 298 InNewSpace(object, scratch, eq, &done); |
341 | 299 |
342 // Record the actual write. | 300 // Record the actual write. |
343 RecordWriteHelper(object, offset, scratch); | 301 RecordWriteHelper(object, offset, scratch); |
344 | 302 |
345 bind(&done); | 303 bind(&done); |
346 | 304 |
347 // Clobber all input registers when running with the debug-code flag | 305 // Clobber all input registers when running with the debug-code flag |
348 // turned on to provoke errors. | 306 // turned on to provoke errors. |
349 if (FLAG_debug_code) { | 307 if (FLAG_debug_code) { |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 ASSERT(fun.is(r1)); | 615 ASSERT(fun.is(r1)); |
658 | 616 |
659 Register expected_reg = r2; | 617 Register expected_reg = r2; |
660 Register code_reg = r3; | 618 Register code_reg = r3; |
661 | 619 |
662 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 620 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
663 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 621 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
664 ldr(expected_reg, | 622 ldr(expected_reg, |
665 FieldMemOperand(code_reg, | 623 FieldMemOperand(code_reg, |
666 SharedFunctionInfo::kFormalParameterCountOffset)); | 624 SharedFunctionInfo::kFormalParameterCountOffset)); |
| 625 mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize)); |
667 ldr(code_reg, | 626 ldr(code_reg, |
668 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); | 627 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); |
669 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 628 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
670 | 629 |
671 ParameterCount expected(expected_reg); | 630 ParameterCount expected(expected_reg); |
672 InvokeCode(code_reg, expected, actual, flag); | 631 InvokeCode(code_reg, expected, actual, flag); |
673 } | 632 } |
674 | 633 |
675 | 634 |
676 void MacroAssembler::InvokeFunction(JSFunction* function, | 635 void MacroAssembler::InvokeFunction(JSFunction* function, |
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 | 1726 |
1768 void CodePatcher::Emit(Address addr) { | 1727 void CodePatcher::Emit(Address addr) { |
1769 masm()->emit(reinterpret_cast<Instr>(addr)); | 1728 masm()->emit(reinterpret_cast<Instr>(addr)); |
1770 } | 1729 } |
1771 #endif // ENABLE_DEBUGGER_SUPPORT | 1730 #endif // ENABLE_DEBUGGER_SUPPORT |
1772 | 1731 |
1773 | 1732 |
1774 } } // namespace v8::internal | 1733 } } // namespace v8::internal |
1775 | 1734 |
1776 #endif // V8_TARGET_ARCH_ARM | 1735 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |