annotate graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectLayout.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children 50c11b9a7fdf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
1 /*
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
4 * redistribute it and/or modify it under the terms of the:
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
5 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
6 * Eclipse Public License version 1.0
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
7 * GNU General Public License version 2
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
8 * GNU Lesser General Public License version 2.1
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
9 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
10 package com.oracle.truffle.ruby.runtime.objects;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
11
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
12 import java.lang.reflect.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
13 import java.util.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
14 import java.util.Map.Entry;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
15
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
16 import sun.misc.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
17
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
18 import com.oracle.truffle.api.nodes.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
19 import com.oracle.truffle.api.nodes.NodeUtil.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
20 import com.oracle.truffle.ruby.runtime.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
21
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
22 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
23 * Maps names of instance variables to storage locations, which are either the offset of a primitive
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
24 * field in {@code RubyBasicObject}, or an index into an object array in {@code RubyBasicObject}.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
25 * Object layouts are chained, with each having zero or one parents.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
26 * <p>
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
27 * Object layouts are immutable, with the methods for adding new instance variables of generalizing
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
28 * the type of existing instance variables returning new object layouts.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
29 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
30 public class ObjectLayout {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
31
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
32 public static final ObjectLayout EMPTY = new ObjectLayout("(empty)");
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
33
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
34 private final String originHint;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
35
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
36 private final ObjectLayout parent;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
37
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
38 private final Map<String, StorageLocation> storageLocations = new HashMap<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
39
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
40 private final int primitiveStorageLocationsUsed;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
41 private final int objectStorageLocationsUsed;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
42
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
43 public static final long FIRST_OFFSET = getFirstOffset();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
44
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
45 private ObjectLayout(String originHint) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
46 this.originHint = originHint;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
47 this.parent = null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
48 primitiveStorageLocationsUsed = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
49 objectStorageLocationsUsed = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
50 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
51
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
52 public ObjectLayout(String originHint, RubyContext context, ObjectLayout parent) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
53 this(originHint, context, parent, new HashMap<String, Class>());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
54 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
55
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
56 public ObjectLayout(String originHint, RubyContext context, ObjectLayout parent, Map<String, Class> storageTypes) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
57 this.originHint = originHint;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
58 this.parent = parent;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
59
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
60 // Start our offsets from where the parent ends
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
61
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
62 int primitiveStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
63 int objectStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
64
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
65 if (parent == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
66 primitiveStorageLocationIndex = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
67 objectStorageLocationIndex = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
68 } else {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
69 primitiveStorageLocationIndex = parent.primitiveStorageLocationsUsed;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
70 objectStorageLocationIndex = parent.objectStorageLocationsUsed;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
71 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
72
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
73 // Go through the variables we've been asked to store
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
74
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
75 for (Entry<String, Class> entry : storageTypes.entrySet()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
76 // TODO(cs): what if parent has it, but we need a more general type?
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
77
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
78 final String name = entry.getKey();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
79 final Class type = entry.getValue();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
80
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
81 if (parent == null || parent.findStorageLocation(name) == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
82 boolean canStoreInPrimitive = false;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
83 int primitivesNeeded = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
84
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
85 if (type == Integer.class) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
86 canStoreInPrimitive = true;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
87 primitivesNeeded = 1;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
88 } else if (type == Double.class) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
89 canStoreInPrimitive = true;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
90 primitivesNeeded = 2;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
91 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
92
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
93 if (canStoreInPrimitive && primitiveStorageLocationIndex + primitivesNeeded <= RubyBasicObject.PRIMITIVE_STORAGE_LOCATIONS_COUNT) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
94 final long offset = FIRST_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * primitiveStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
95 final int mask = 1 << primitiveStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
96
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
97 StorageLocation newStorageLocation = null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
98
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
99 if (type == Integer.class) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
100 newStorageLocation = new FixnumStorageLocation(this, offset, mask);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
101 } else if (type == Double.class) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
102 newStorageLocation = new FloatStorageLocation(this, offset, mask);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
103 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
104
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
105 storageLocations.put(entry.getKey(), newStorageLocation);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
106 primitiveStorageLocationIndex += primitivesNeeded;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
107 } else {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
108 if (canStoreInPrimitive && context.getConfiguration().getPrintSpiltInstanceVariables()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
109 context.implementationMessage("instance variable %s of type %s spilt due to lack of space", name, type.getName());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
110 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
111
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
112 final ObjectStorageLocation newStorageLocation = new ObjectStorageLocation(this, objectStorageLocationIndex);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
113 storageLocations.put(entry.getKey(), newStorageLocation);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
114 objectStorageLocationIndex++;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
115 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
116 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
117 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
118
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
119 primitiveStorageLocationsUsed = primitiveStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
120 objectStorageLocationsUsed = objectStorageLocationIndex;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
121 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
122
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
123 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
124 * Create a new version of this layout, but with a different parent. The new parent probably
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
125 * comes from the same Ruby class as it did, but it's a new layout because layouts are
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
126 * immutable, so modifications to the superclass yields a new layout.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
127 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
128 public ObjectLayout renew(RubyContext context, ObjectLayout newParent) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
129 return new ObjectLayout(originHint + ".renewed", context, newParent, getStorageTypes());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
130 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
131
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
132 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
133 * Create a new version of this layout but with a new variable.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
134 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
135 public ObjectLayout withNewVariable(RubyContext context, String name, Class type) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
136 final Map<String, Class> storageTypes = getStorageTypes();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
137 storageTypes.put(name, type);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
138 return new ObjectLayout(originHint + ".withnew", context, parent, storageTypes);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
139 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
140
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
141 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
142 * Create a new version of this layout but with an existing variable generalized to support any
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
143 * type.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
144 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
145 public ObjectLayout withGeneralisedVariable(RubyContext context, String name) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
146 return withNewVariable(context, name, Object.class);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
147 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
148
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
149 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
150 * Get a map of instance variable names to the type that they store.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
151 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
152 public Map<String, Class> getStorageTypes() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
153 Map<String, Class> storageTypes = new HashMap<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
154
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
155 for (Entry<String, StorageLocation> entry : storageLocations.entrySet()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
156 final String name = entry.getKey();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
157 final StorageLocation storageLocation = entry.getValue();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
158
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
159 if (storageLocation.getStoredClass() != null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
160 storageTypes.put(name, storageLocation.getStoredClass());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
161 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
162 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
163
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
164 return storageTypes;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
165 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
166
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
167 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
168 * Get a map of instance variable names to the type that they store, but including both this
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
169 * layout and all parent layouts.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
170 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
171 public Map<String, StorageLocation> getAllStorageLocations() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
172 final Map<String, StorageLocation> allStorageLocations = new HashMap<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
173
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
174 allStorageLocations.putAll(storageLocations);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
175
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
176 if (parent != null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
177 allStorageLocations.putAll(parent.getAllStorageLocations());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
178 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
179
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
180 return allStorageLocations;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
181 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
182
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
183 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
184 * Find a storage location from a name, including in parents.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
185 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
186 public StorageLocation findStorageLocation(String name) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
187 final StorageLocation storageLocation = storageLocations.get(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
188
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
189 if (storageLocation != null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
190 return storageLocation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
191 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
192
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
193 if (parent == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
194 return null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
195 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
196
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
197 return parent.findStorageLocation(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
198 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
199
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
200 public int getObjectStorageLocationsUsed() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
201 return objectStorageLocationsUsed;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
202 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
203
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
204 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
205 * Does this layout include another layout? That is, is that other layout somewhere in the chain
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
206 * of parents? We say 'include' because all of the variables in a parent layout are available in
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
207 * your layout as well.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
208 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
209 public boolean contains(ObjectLayout other) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
210 ObjectLayout layout = this;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
211
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
212 do {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
213 if (other == layout) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
214 return true;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
215 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
216
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
217 layout = layout.parent;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
218 } while (layout != null);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
219
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
220 return false;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
221 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
222
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
223 public String getOriginHint() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
224 return originHint;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
225 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
226
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
227 private static long getFirstOffset() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
228 try {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
229 final Field fieldOffsetProviderField = NodeUtil.class.getDeclaredField("unsafeFieldOffsetProvider");
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
230 fieldOffsetProviderField.setAccessible(true);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
231 final FieldOffsetProvider fieldOffsetProvider = (FieldOffsetProvider) fieldOffsetProviderField.get(null);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
232
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
233 final Field firstPrimitiveField = RubyBasicObject.class.getDeclaredField("primitiveStorageLocation01");
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
234 return fieldOffsetProvider.objectFieldOffset(firstPrimitiveField);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
235 } catch (NoSuchFieldException | IllegalAccessException e) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
236 throw new RuntimeException(e);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
237 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
238 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
239
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
240 }