Chromium Code Reviews| Index: runtime/vm/stub_code_arm64.cc |
| =================================================================== |
| --- runtime/vm/stub_code_arm64.cc (revision 35264) |
| +++ runtime/vm/stub_code_arm64.cc (working copy) |
| @@ -324,8 +324,72 @@ |
| } |
| +DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
| + |
| +// Helper stub to implement Assembler::StoreIntoObject. |
| +// Input parameters: |
| +// R0: Address being stored |
| void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
| - __ Stop("GenerateUpdateStoreBufferStub"); |
| + // Save values being destroyed. |
| + __ Push(R1); |
| + __ Push(R2); |
| + __ Push(R3); |
| + |
| + Label add_to_buffer; |
| + // Check whether this object has already been remembered. Skip adding to the |
| + // store buffer if the object is in the store buffer already. |
| + // Spilled: R1, R2, R3 |
| + // R0: Address being stored |
| + __ LoadFieldFromOffset(R2, R0, Object::tags_offset()); |
| + |
| + __ tsti(R2, 1 << RawObject::kRememberedBit); |
| + __ b(&add_to_buffer, EQ); |
| + __ Pop(R3); |
| + __ Pop(R2); |
| + __ Pop(R1); |
| + __ ret(); |
|
regis
2014/04/22 18:45:32
How frequent is this ret()?
If we return frequentl
zra
2014/04/22 19:44:02
Done.
|
| + |
| + __ Bind(&add_to_buffer); |
| + __ orri(R2, R2, 1 << RawObject::kRememberedBit); |
| + __ StoreFieldToOffset(R2, R0, Object::tags_offset()); |
| + |
| + // Load the isolate out of the context. |
| + // Spilled: R1, R2, R3. |
| + // R0: address being stored. |
| + __ LoadFieldFromOffset(R1, CTX, Context::isolate_offset()); |
| + |
| + // Load the StoreBuffer block out of the isolate. Then load top_ out of the |
| + // StoreBufferBlock and add the address to the pointers_. |
| + // R1: isolate. |
| + __ LoadFromOffset(R1, R1, Isolate::store_buffer_offset()); |
| + __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset()); |
| + __ add(R3, R1, Operand(R2, LSL, 3)); |
| + __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset()); |
| + |
| + // Increment top_ and check for overflow. |
| + // R2: top_. |
| + // R1: StoreBufferBlock. |
| + Label L; |
| + __ add(R2, R2, Operand(1)); |
| + __ StoreToOffset(R2, R1, StoreBufferBlock::top_offset()); |
| + __ CompareImmediate(R2, StoreBufferBlock::kSize, PP); |
| + // Restore values. |
| + __ Pop(R3); |
| + __ Pop(R2); |
| + __ Pop(R1); |
| + __ b(&L, EQ); |
| + __ ret(); |
| + |
| + // Handle overflow: Call the runtime leaf function. |
| + __ Bind(&L); |
| + // Setup frame, push callee-saved registers. |
| + |
| + __ EnterCallRuntimeFrame(0 * kWordSize); |
| + __ LoadFieldFromOffset(R0, CTX, Context::isolate_offset()); |
| + __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| + // Restore callee-saved registers, tear down frame. |
| + __ LeaveCallRuntimeFrame(); |
| + __ ret(); |
| } |