| 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 mov(ip, Operand(Page::kPageAlignmentMask)); // Load mask only once. | 255 // This is how much we shift the remembered set bit offset to get the |
| 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; |
| 256 | 259 |
| 257 // Calculate region number. | 260 Label fast; |
| 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 // Calculate page address. | 262 // Compute the bit offset in the remembered set. |
| 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 |
| 263 bic(object, object, Operand(ip)); | 273 bic(object, object, Operand(ip)); |
| 264 | 274 |
| 265 // Mark region dirty. | 275 // If the bit offset lies beyond the normal remembered set range, it is in |
| 266 ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset)); | 276 // the extra remembered set area of a large object. |
| 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)); |
| 267 mov(ip, Operand(1)); | 309 mov(ip, Operand(1)); |
| 268 orr(scratch, scratch, Operand(ip, LSL, offset)); | 310 orr(scratch, scratch, Operand(ip, LSL, offset)); |
| 269 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); | 311 str(scratch, MemOperand(object)); |
| 270 } | 312 } |
| 271 | 313 |
| 272 | 314 |
| 273 void MacroAssembler::InNewSpace(Register object, | 315 void MacroAssembler::InNewSpace(Register object, |
| 274 Register scratch, | 316 Register scratch, |
| 275 Condition cc, | 317 Condition cc, |
| 276 Label* branch) { | 318 Label* branch) { |
| 277 ASSERT(cc == eq || cc == ne); | 319 ASSERT(cc == eq || cc == ne); |
| 278 and_(scratch, object, Operand(ExternalReference::new_space_mask())); | 320 and_(scratch, object, Operand(ExternalReference::new_space_mask())); |
| 279 cmp(scratch, Operand(ExternalReference::new_space_start())); | 321 cmp(scratch, Operand(ExternalReference::new_space_start())); |
| 280 b(cc, branch); | 322 b(cc, branch); |
| 281 } | 323 } |
| 282 | 324 |
| 283 | 325 |
| 284 // Will clobber 4 registers: object, offset, scratch, ip. The | 326 // Will clobber 4 registers: object, offset, scratch, ip. The |
| 285 // register 'object' contains a heap object pointer. The heap object | 327 // register 'object' contains a heap object pointer. The heap object |
| 286 // tag is shifted away. | 328 // tag is shifted away. |
| 287 void MacroAssembler::RecordWrite(Register object, Register offset, | 329 void MacroAssembler::RecordWrite(Register object, Register offset, |
| 288 Register scratch) { | 330 Register scratch) { |
| 289 // The compiled code assumes that record write doesn't change the | 331 // The compiled code assumes that record write doesn't change the |
| 290 // context register, so we check that none of the clobbered | 332 // context register, so we check that none of the clobbered |
| 291 // registers are cp. | 333 // registers are cp. |
| 292 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); | 334 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); |
| 293 | 335 |
| 294 Label done; | 336 Label done; |
| 295 | 337 |
| 296 // First, test that the object is not in the new space. We cannot set | 338 // First, test that the object is not in the new space. We cannot set |
| 297 // region marks for new space pages. | 339 // remembered set bits in the new space. |
| 298 InNewSpace(object, scratch, eq, &done); | 340 InNewSpace(object, scratch, eq, &done); |
| 299 | 341 |
| 300 // Record the actual write. | 342 // Record the actual write. |
| 301 RecordWriteHelper(object, offset, scratch); | 343 RecordWriteHelper(object, offset, scratch); |
| 302 | 344 |
| 303 bind(&done); | 345 bind(&done); |
| 304 | 346 |
| 305 // Clobber all input registers when running with the debug-code flag | 347 // Clobber all input registers when running with the debug-code flag |
| 306 // turned on to provoke errors. | 348 // turned on to provoke errors. |
| 307 if (FLAG_debug_code) { | 349 if (FLAG_debug_code) { |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 ASSERT(fun.is(r1)); | 612 ASSERT(fun.is(r1)); |
| 571 | 613 |
| 572 Register expected_reg = r2; | 614 Register expected_reg = r2; |
| 573 Register code_reg = r3; | 615 Register code_reg = r3; |
| 574 | 616 |
| 575 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 617 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 576 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 618 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 577 ldr(expected_reg, | 619 ldr(expected_reg, |
| 578 FieldMemOperand(code_reg, | 620 FieldMemOperand(code_reg, |
| 579 SharedFunctionInfo::kFormalParameterCountOffset)); | 621 SharedFunctionInfo::kFormalParameterCountOffset)); |
| 580 mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize)); | |
| 581 ldr(code_reg, | 622 ldr(code_reg, |
| 582 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); | 623 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); |
| 583 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 624 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 584 | 625 |
| 585 ParameterCount expected(expected_reg); | 626 ParameterCount expected(expected_reg); |
| 586 InvokeCode(code_reg, expected, actual, flag); | 627 InvokeCode(code_reg, expected, actual, flag); |
| 587 } | 628 } |
| 588 | 629 |
| 589 | 630 |
| 590 void MacroAssembler::InvokeFunction(JSFunction* function, | 631 void MacroAssembler::InvokeFunction(JSFunction* function, |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 | 1722 |
| 1682 void CodePatcher::Emit(Address addr) { | 1723 void CodePatcher::Emit(Address addr) { |
| 1683 masm()->emit(reinterpret_cast<Instr>(addr)); | 1724 masm()->emit(reinterpret_cast<Instr>(addr)); |
| 1684 } | 1725 } |
| 1685 #endif // ENABLE_DEBUGGER_SUPPORT | 1726 #endif // ENABLE_DEBUGGER_SUPPORT |
| 1686 | 1727 |
| 1687 | 1728 |
| 1688 } } // namespace v8::internal | 1729 } } // namespace v8::internal |
| 1689 | 1730 |
| 1690 #endif // V8_TARGET_ARCH_ARM | 1731 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |