| 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 Register offset, | 243 Register offset, |
| 244 Register scratch) { | 244 Register scratch) { |
| 245 if (FLAG_debug_code) { | 245 if (FLAG_debug_code) { |
| 246 // Check that the object is not in new space. | 246 // Check that the object is not in new space. |
| 247 Label not_in_new_space; | 247 Label not_in_new_space; |
| 248 InNewSpace(object, scratch, ne, ¬_in_new_space); | 248 InNewSpace(object, scratch, ne, ¬_in_new_space); |
| 249 Abort("new-space object passed to RecordWriteHelper"); | 249 Abort("new-space object passed to RecordWriteHelper"); |
| 250 bind(¬_in_new_space); | 250 bind(¬_in_new_space); |
| 251 } | 251 } |
| 252 | 252 |
| 253 // This is how much we shift the remembered set bit offset to get the | 253 mov(ip, Operand(Page::kPageAlignmentMask)); // Load mask only once. |
| 254 // offset of the word in the remembered set. We divide by kBitsPerInt (32, | |
| 255 // shift right 5) and then multiply by kIntSize (4, shift left 2). | |
| 256 const int kRSetWordShift = 3; | |
| 257 | 254 |
| 258 Label fast; | 255 // Calculate region number. |
| 256 add(offset, object, Operand(offset)); // Add offset into the object. |
| 257 and_(offset, offset, Operand(ip)); // Offset into page of the object. |
| 258 mov(offset, Operand(offset, LSR, Page::kRegionSizeLog2)); |
| 259 | 259 |
| 260 // Compute the bit offset in the remembered set. | 260 // Calculate page address. |
| 261 // object: heap object pointer (with tag) | |
| 262 // offset: offset to store location from the object | |
| 263 mov(ip, Operand(Page::kPageAlignmentMask)); // load mask only once | |
| 264 and_(scratch, object, Operand(ip)); // offset into page of the object | |
| 265 add(offset, scratch, Operand(offset)); // add offset into the object | |
| 266 mov(offset, Operand(offset, LSR, kObjectAlignmentBits)); | |
| 267 | |
| 268 // Compute the page address from the heap object pointer. | |
| 269 // object: heap object pointer (with tag) | |
| 270 // offset: bit offset of store position in the remembered set | |
| 271 bic(object, object, Operand(ip)); | 261 bic(object, object, Operand(ip)); |
| 272 | 262 |
| 273 // If the bit offset lies beyond the normal remembered set range, it is in | 263 // Mark region dirty. |
| 274 // the extra remembered set area of a large object. | 264 ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
| 275 // object: page start | |
| 276 // offset: bit offset of store position in the remembered set | |
| 277 cmp(offset, Operand(Page::kPageSize / kPointerSize)); | |
| 278 b(lt, &fast); | |
| 279 | |
| 280 // Adjust the bit offset to be relative to the start of the extra | |
| 281 // remembered set and the start address to be the address of the extra | |
| 282 // remembered set. | |
| 283 sub(offset, offset, Operand(Page::kPageSize / kPointerSize)); | |
| 284 // Load the array length into 'scratch' and multiply by four to get the | |
| 285 // size in bytes of the elements. | |
| 286 ldr(scratch, MemOperand(object, Page::kObjectStartOffset | |
| 287 + FixedArray::kLengthOffset)); | |
| 288 mov(scratch, Operand(scratch, LSL, kObjectAlignmentBits)); | |
| 289 // Add the page header (including remembered set), array header, and array | |
| 290 // body size to the page address. | |
| 291 add(object, object, Operand(Page::kObjectStartOffset | |
| 292 + FixedArray::kHeaderSize)); | |
| 293 add(object, object, Operand(scratch)); | |
| 294 | |
| 295 bind(&fast); | |
| 296 // Get address of the rset word. | |
| 297 // object: start of the remembered set (page start for the fast case) | |
| 298 // offset: bit offset of store position in the remembered set | |
| 299 bic(scratch, offset, Operand(kBitsPerInt - 1)); // clear the bit offset | |
| 300 add(object, object, Operand(scratch, LSR, kRSetWordShift)); | |
| 301 // Get bit offset in the rset word. | |
| 302 // object: address of remembered set word | |
| 303 // offset: bit offset of store position | |
| 304 and_(offset, offset, Operand(kBitsPerInt - 1)); | |
| 305 | |
| 306 ldr(scratch, MemOperand(object)); | |
| 307 mov(ip, Operand(1)); | 265 mov(ip, Operand(1)); |
| 308 orr(scratch, scratch, Operand(ip, LSL, offset)); | 266 orr(scratch, scratch, Operand(ip, LSL, offset)); |
| 309 str(scratch, MemOperand(object)); | 267 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
| 310 } | 268 } |
| 311 | 269 |
| 312 | 270 |
| 313 void MacroAssembler::InNewSpace(Register object, | 271 void MacroAssembler::InNewSpace(Register object, |
| 314 Register scratch, | 272 Register scratch, |
| 315 Condition cc, | 273 Condition cc, |
| 316 Label* branch) { | 274 Label* branch) { |
| 317 ASSERT(cc == eq || cc == ne); | 275 ASSERT(cc == eq || cc == ne); |
| 318 and_(scratch, object, Operand(ExternalReference::new_space_mask())); | 276 and_(scratch, object, Operand(ExternalReference::new_space_mask())); |
| 319 cmp(scratch, Operand(ExternalReference::new_space_start())); | 277 cmp(scratch, Operand(ExternalReference::new_space_start())); |
| 320 b(cc, branch); | 278 b(cc, branch); |
| 321 } | 279 } |
| 322 | 280 |
| 323 | 281 |
| 324 // Will clobber 4 registers: object, offset, scratch, ip. The | 282 // Will clobber 4 registers: object, offset, scratch, ip. The |
| 325 // register 'object' contains a heap object pointer. The heap object | 283 // register 'object' contains a heap object pointer. The heap object |
| 326 // tag is shifted away. | 284 // tag is shifted away. |
| 327 void MacroAssembler::RecordWrite(Register object, Register offset, | 285 void MacroAssembler::RecordWrite(Register object, Register offset, |
| 328 Register scratch) { | 286 Register scratch) { |
| 329 // The compiled code assumes that record write doesn't change the | 287 // The compiled code assumes that record write doesn't change the |
| 330 // context register, so we check that none of the clobbered | 288 // context register, so we check that none of the clobbered |
| 331 // registers are cp. | 289 // registers are cp. |
| 332 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); | 290 ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp)); |
| 333 | 291 |
| 334 Label done; | 292 Label done; |
| 335 | 293 |
| 336 // First, test that the object is not in the new space. We cannot set | 294 // First, test that the object is not in the new space. We cannot set |
| 337 // remembered set bits in the new space. | 295 // region marks for new space pages. |
| 338 InNewSpace(object, scratch, eq, &done); | 296 InNewSpace(object, scratch, eq, &done); |
| 339 | 297 |
| 340 // Record the actual write. | 298 // Record the actual write. |
| 341 RecordWriteHelper(object, offset, scratch); | 299 RecordWriteHelper(object, offset, scratch); |
| 342 | 300 |
| 343 bind(&done); | 301 bind(&done); |
| 344 | 302 |
| 345 // Clobber all input registers when running with the debug-code flag | 303 // Clobber all input registers when running with the debug-code flag |
| 346 // turned on to provoke errors. | 304 // turned on to provoke errors. |
| 347 if (FLAG_debug_code) { | 305 if (FLAG_debug_code) { |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 ASSERT(fun.is(r1)); | 568 ASSERT(fun.is(r1)); |
| 611 | 569 |
| 612 Register expected_reg = r2; | 570 Register expected_reg = r2; |
| 613 Register code_reg = r3; | 571 Register code_reg = r3; |
| 614 | 572 |
| 615 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 573 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 616 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 574 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 617 ldr(expected_reg, | 575 ldr(expected_reg, |
| 618 FieldMemOperand(code_reg, | 576 FieldMemOperand(code_reg, |
| 619 SharedFunctionInfo::kFormalParameterCountOffset)); | 577 SharedFunctionInfo::kFormalParameterCountOffset)); |
| 578 mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize)); |
| 620 ldr(code_reg, | 579 ldr(code_reg, |
| 621 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); | 580 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); |
| 622 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 581 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 623 | 582 |
| 624 ParameterCount expected(expected_reg); | 583 ParameterCount expected(expected_reg); |
| 625 InvokeCode(code_reg, expected, actual, flag); | 584 InvokeCode(code_reg, expected, actual, flag); |
| 626 } | 585 } |
| 627 | 586 |
| 628 | 587 |
| 629 void MacroAssembler::InvokeFunction(JSFunction* function, | 588 void MacroAssembler::InvokeFunction(JSFunction* function, |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 } | 1677 } |
| 1719 | 1678 |
| 1720 | 1679 |
| 1721 void CodePatcher::Emit(Address addr) { | 1680 void CodePatcher::Emit(Address addr) { |
| 1722 masm()->emit(reinterpret_cast<Instr>(addr)); | 1681 masm()->emit(reinterpret_cast<Instr>(addr)); |
| 1723 } | 1682 } |
| 1724 #endif // ENABLE_DEBUGGER_SUPPORT | 1683 #endif // ENABLE_DEBUGGER_SUPPORT |
| 1725 | 1684 |
| 1726 | 1685 |
| 1727 } } // namespace v8::internal | 1686 } } // namespace v8::internal |
| OLD | NEW |