01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
03: * notice. All rights reserved.
04: */
05: package com.tc.object.bytecode;
06:
07: import com.tc.asm.Label;
08: import com.tc.asm.MethodVisitor;
09: import com.tc.asm.Type;
10:
11: public abstract class AbstractVolatileFieldMethodVisitor extends
12: MaxLocalVarStoreDetectingMethodAdapter {
13: public AbstractVolatileFieldMethodVisitor(MethodVisitor mv) {
14: super (mv);
15: }
16:
17: public abstract void modifyVolatileValue(int tcobjectVarStore,
18: Label labelCommitVolatile);
19:
20: public void doVolatileBeginCommitLogic(String fieldName,
21: int nextFreeLocalVarStore) {
22: int tcobject_var_store = nextFreeLocalVarStore + 1;
23: int exception_var_store = tcobject_var_store + 1;
24:
25: // load the reference to the currently executing object instance
26: mv.visitVarInsn(ALOAD, 0);
27:
28: // look up the TCObject from the TC manager that corresponds
29: // to the current object instance
30: mv.visitMethodInsn(INVOKESTATIC, Type
31: .getInternalName(ManagerUtil.class),
32: "lookupExistingOrNull",
33: "(Ljava/lang/Object;)Lcom/tc/object/TCObject;");
34:
35: // store the TCObject in the appropriate local variable slot
36: mv.visitVarInsn(ASTORE, tcobject_var_store);
37:
38: // the labels that are used in the code ahead
39: Label label_begin_volatile = new Label();
40: Label label_exception = new Label();
41: Label label_commit_volatile = new Label();
42: Label label_tcobject_null = new Label();
43:
44: // setup the try catch block
45: mv.visitTryCatchBlock(label_begin_volatile, label_exception,
46: label_exception, null);
47:
48: mv.visitVarInsn(ALOAD, 0);
49:
50: // check if the TCObject instance is null, and jump over the state
51: // modification code that follows
52: mv.visitVarInsn(ALOAD, tcobject_var_store);
53: mv.visitJumpInsn(IFNULL, label_tcobject_null);
54:
55: // // call the begin volatile method on the managed object
56: mv.visitLabel(label_begin_volatile);
57: mv.visitVarInsn(ALOAD, tcobject_var_store);
58: mv.visitLdcInsn(fieldName);
59: mv.visitInsn(ICONST_2);
60: mv.visitMethodInsn(INVOKESTATIC,
61: "com/tc/object/bytecode/ManagerUtil", "beginVolatile",
62: "(Lcom/tc/object/TCObject;Ljava/lang/String;I)V");
63:
64: modifyVolatileValue(tcobject_var_store, label_commit_volatile);
65:
66: mv.visitJumpInsn(GOTO, label_commit_volatile);
67:
68: // ensure that commit is called in case an exception occurs
69: mv.visitLabel(label_exception);
70: mv.visitVarInsn(ASTORE, exception_var_store);
71: mv.visitVarInsn(ALOAD, tcobject_var_store);
72: mv.visitLdcInsn(fieldName);
73: mv.visitMethodInsn(INVOKESTATIC,
74: "com/tc/object/bytecode/ManagerUtil", "commitVolatile",
75: "(Lcom/tc/object/TCObject;Ljava/lang/String;)V");
76: mv.visitVarInsn(ALOAD, exception_var_store);
77: mv.visitInsn(ATHROW);
78:
79: // call the commit volatile on the managed object
80: mv.visitLabel(label_commit_volatile);
81: mv.visitVarInsn(ALOAD, tcobject_var_store);
82: mv.visitLdcInsn(fieldName);
83: mv.visitMethodInsn(INVOKESTATIC,
84: "com/tc/object/bytecode/ManagerUtil", "commitVolatile",
85: "(Lcom/tc/object/TCObject;Ljava/lang/String;)V");
86:
87: mv.visitLabel(label_tcobject_null);
88: }
89: }
|