root/trunk/ProjectFortress/src/com/sun/fortress/interpreter/env/ReferenceCell.java @ 2700

Revision 2700, 5.9 KB (checked in by chf, 15 months ago)

Small cleanups

Line 
1 /*******************************************************************************
2    Copyright 2008 Sun Microsystems, Inc.,
3    4150 Network Circle, Santa Clara, California 95054, U.S.A.
4    All rights reserved.
5
6    U.S. Government Rights - Commercial software.
7    Government users are subject to the Sun Microsystems, Inc. standard
8    license agreement and applicable provisions of the FAR and its supplements.
9
10    Use is subject to license terms.
11
12    This distribution may include materials developed by third parties.
13
14    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16******************************************************************************/
17
18package com.sun.fortress.interpreter.env;
19
20import static com.sun.fortress.exceptions.InterpreterBug.bug;
21import com.sun.fortress.exceptions.transactions.AbortedException;
22import com.sun.fortress.exceptions.transactions.PanicException;
23import com.sun.fortress.interpreter.evaluator.tasks.FortressTaskRunner;
24import com.sun.fortress.interpreter.evaluator.transactions.Transaction;
25
26import java.util.concurrent.atomic.AtomicInteger;
27
28import com.sun.fortress.interpreter.evaluator.types.FType;
29import com.sun.fortress.interpreter.evaluator.values.FValue;
30
31/**
32 * What the interpreter stores mutable things (fields, variables)
33 * in.  It will eventually acquire transactional semantics.
34 */
35
36public class ReferenceCell extends IndirectionCell {
37    private FType theType;
38    ValueNode node;
39
40    // for debugging
41    static final AtomicInteger counter = new AtomicInteger(0);
42    final int id;
43
44    public ReferenceCell() {
45        super();
46        node = new ValueNode();
47        id = counter.getAndIncrement();
48    }
49
50    public ReferenceCell(FType t, FValue v) {
51        super();
52        theType = t;
53        node = new ValueNode(v);
54        id = counter.getAndIncrement();
55    }
56
57    public ReferenceCell(FType t) {
58        super();
59        theType = t;
60        node = new ValueNode();
61        id = counter.getAndIncrement();
62    }
63
64    public FType getType() { return theType;}
65    public String toString() { return "ReferenceCell" + id;}
66
67
68    private boolean transactionIsCommitted(Transaction w) {
69        if (w == null) return true;
70        else if (w.isCommitted()) return true;
71        return false;
72    }
73
74    private boolean transactionIsAbortedOrOrphaned(Transaction w) {
75        if (w == null) return false;
76        else if (w.isAborted()) return true;
77        else if (w.isOrphaned()) return true;
78        else return false;
79        }
80
81    private boolean transactionIsNotActive(Transaction w) {
82        if (w == null) return false;
83        else if (w.isAborted()) return true;
84        else if (w.isOrphaned()) return true;
85        else if (w.isCommitted()) return true;
86        else return false;
87    }
88
89
90    private synchronized void cleanup() {
91        Transaction w = node.getWriter();
92        while (w != null && transactionIsNotActive(w)) {
93            if (transactionIsAbortedOrOrphaned(w)) {
94                node = node.getOld();
95            } else {
96                assert(transactionIsCommitted(w));
97                Transaction p = w.getParent();
98                if (p == null) {
99                    node = new ValueNode(node.getValue(), node.getOld().getReaders());
100                } else  {
101                    node = new ValueNode(node.getValue(), p, node.getOld());
102                }
103            }
104            if (node != null) {
105                w = node.getWriter();
106            } else {
107                node = new ValueNode();
108                return;
109            }
110        }
111    }
112
113    public synchronized void assignValue(FValue f2) {
114        Transaction me  = FortressTaskRunner.getTransaction();
115        cleanup();
116        // writer is either active, or null
117        if (me == null) { // top level assignment
118            ValueNode temp = node;
119            node = new ValueNode(f2);
120            temp.AbortAllReadersAndWriters();
121        } else if (!me.isActive()) {
122            throw new AbortedException(me, "Somebody killed me ");
123        } else {
124            node.resolveReadWriteConflicts();
125            cleanup();
126            if (!me.isActive())
127                throw new AbortedException(me, "Somebody killed me ");     
128
129            Transaction w = node.getWriter();
130
131            if (w == null || w.isAncestorOf(me)) {
132                node = new ValueNode(f2, me, node);
133                if (Transaction.debug) me.addWrite(this, f2);
134            } else if (w.isActive()) {
135                                // Cleanup got us to a parent node with an active writer
136                assignValue(f2);
137            }
138        }
139    }
140
141    public synchronized FValue getValue() {
142        Transaction me  = FortressTaskRunner.getTransaction();
143        // Top Level transaction
144        if (me == null) {
145                        while (node.getWriter() != null) {
146                                node.AbortWriter();
147                                cleanup();
148                        }
149            return node.getValue();
150        }
151
152        if (!me.isActive()) throw new AbortedException(me, "Somebody killed me");   
153
154        cleanup(); 
155
156        Transaction w = node.getWriter();
157        if (w == me) {
158            return node.getValue();
159        } else if (w == null || w.isAncestorOf(me)) {
160            node.addReader();
161            if (Transaction.debug) me.addRead(this, node.getValue());
162            return node.getValue();
163        } else if (w.isActive()) {     
164            node.resolveWriteConflict();
165        }
166        return getValue();
167    }
168
169    public FValue getValueNull() {
170        return getValue();
171    }
172
173
174    public void storeValue(FValue f2) {
175        if (node.getValue() != null)
176            bug("Internal error, second store of indirection cell");
177        assignValue(f2);
178    }
179
180    public void storeType(FType f2) {
181        if (theType != null)
182            bug("Internal error, second store of type");
183        theType = f2;
184    }
185   
186    public boolean isInitialized() {
187        return getValue() != null;
188    }
189
190}
Note: See TracBrowser for help on using the browser.