Index: runtime/vm/stub_code_arm.cc |
=================================================================== |
--- runtime/vm/stub_code_arm.cc (revision 21081) |
+++ runtime/vm/stub_code_arm.cc (working copy) |
@@ -356,8 +356,52 @@ |
} |
+DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
+ |
+// Helper stub to implement Assembler::StoreIntoObject. |
+// Input parameters: |
+// R0: Address (i.e. object) being stored into. |
void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
- __ Unimplemented("UpdateStoreBuffer stub"); |
+ // Save values being destroyed. |
+ __ PushList((1 << R1) | (1 << R2) | (1 << R3)); |
+ |
+ // Load the isolate out of the context. |
+ // Spilled: R1, R2, R3. |
+ // R0: Address being stored. |
+ __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); |
+ |
+ // Load top_ out of the StoreBufferBlock and add the address to the pointers_. |
+ // R1: Isolate. |
+ intptr_t store_buffer_offset = Isolate::store_buffer_block_offset(); |
+ __ LoadFromOffset(kLoadWord, R2, R1, |
+ store_buffer_offset + StoreBufferBlock::top_offset()); |
+ __ add(R3, R1, ShifterOperand(R2, LSL, 2)); |
+ __ StoreToOffset(kStoreWord, R0, R3, |
+ store_buffer_offset + StoreBufferBlock::pointers_offset()); |
+ |
+ // Increment top_ and check for overflow. |
+ // R2: top_ |
+ // R1: Isolate |
+ Label L; |
+ __ add(R2, R2, ShifterOperand(1)); |
+ __ StoreToOffset(kStoreWord, R2, R1, |
+ store_buffer_offset + StoreBufferBlock::top_offset()); |
+ __ CompareImmediate(R2, StoreBufferBlock::kSize); |
+ // Restore values. |
+ __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
+ __ b(&L, EQ); |
+ __ Ret(); |
+ |
+ // Handle overflow: Call the runtime leaf function. |
+ __ Bind(&L); |
+ // Setup frame, push callee-saved registers. |
+ |
+ __ EnterCallRuntimeFrame(0 * kWordSize); |
+ __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
+ __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); |
+ // Restore callee-saved registers, tear down frame. |
+ __ LeaveCallRuntimeFrame(); |
+ __ Ret(); |
} |