From 5eb6a4f080edc798a18c2c637cf29650f0cc193f Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 29 Mar 2009 16:05:59 +0000 Subject: Add experimental strict property access option, which is off by default. --- .../amazon/carbonado/gen/StorableGenerator.java | 37 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'src/main/java/com/amazon') diff --git a/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java b/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java index 204508c..3b2287a 100644 --- a/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/gen/StorableGenerator.java @@ -184,6 +184,16 @@ public final class StorableGenerator { cAbstractCache = new WeakIdentityMap(); } + // When true, calls to get uninitialized properties throw an + // IllegalStateException. By default it is false, but the default will + // change to true when query projection is supported. + private static final boolean cStrictAccess; + + static { + String value = System.getProperty(StorableGenerator.class.getName() + ".strictAccess"); + cStrictAccess = value != null && value.equals("true"); + } + // There are three flavors of equals methods, used by addEqualsMethod. private static final int EQUAL_KEYS = 0; private static final int EQUAL_PROPERTIES = 1; @@ -468,8 +478,10 @@ public final class StorableGenerator { requireStateField = true; } else { // Double words are volatile to prevent word tearing - // without explicit synchronization. - mClassFile.addField(Modifiers.PROTECTED.toVolatile(type.isDoubleWord()), + // without explicit synchronization. When strict access + // is enabled, all access methods are synchronized anyhow. + boolean isVolatile = (!cStrictAccess) && type.isDoubleWord(); + mClassFile.addField(Modifiers.PROTECTED.toVolatile(isVolatile), name, type); requireStateField = true; } @@ -501,16 +513,31 @@ public final class StorableGenerator { } } - if (property.isJoin()) { + if (cStrictAccess || property.isJoin()) { // Synchronization is required for join property - // accessors, as they may alter bit masks. + // accessors, as they may alter bit masks. Synchronization is + // also required when strict access is enabled. mi.setModifiers(mi.getModifiers().toSynchronized(true)); } // Now add code that actually gets the property value. CodeBuilder b = new CodeBuilder(mi); - if (property.isJoin()) { + if (!property.isJoin()) { + if (cStrictAccess) { + // Make sure property state allows access. + b.loadThis(); + b.loadField(stateFieldName, TypeDesc.INT); + b.loadConstant(PROPERTY_STATE_MASK << ((ordinal & 0xf) * 2)); + b.math(Opcode.IAND); + Label isValid = b.createLabel(); + b.ifZeroComparisonBranch(isValid, "!="); + CodeBuilderUtil.throwConcatException + (b, IllegalStateException.class, + "Cannot access uninitialized property: ", name); + isValid.setLocation(); + } + } else { // Join properties support on-demand loading. // Check if property has been loaded. -- cgit v1.2.3