You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2016/03/05 01:51:27 UTC

[27/38] incubator-geode git commit: collapsed AddressableStoredObject into StoredObject changed product code to use the StoredObject interface instead of internal class implementations of it

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index 67e641a..2c36b32 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@ -17,10 +17,7 @@
 package com.gemstone.gemfire.internal.cache.tier.sockets;
 
 import com.gemstone.gemfire.internal.*;
-import com.gemstone.gemfire.internal.cache.CachedDeserializable;
-import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
 import com.gemstone.gemfire.internal.offheap.AddressableMemoryManager;
-import com.gemstone.gemfire.internal.offheap.ObjectStoredAsAddress;
 import com.gemstone.gemfire.internal.offheap.StoredObject;
 
 import java.io.*;
@@ -121,17 +118,17 @@ public class Part {
   public void setPartState(StoredObject so, boolean isObject) {
     if (isObject) {
       this.typeCode = OBJECT_CODE;
-    } else if (so.getValueSizeInBytes() == 0) {
+    } else if (so.getDataSize() == 0) {
       this.typeCode = EMPTY_BYTEARRAY_CODE;
       this.part = EMPTY_BYTE_ARRAY;
       return;
     } else {
       this.typeCode = BYTE_CODE;
     }
-    if (so instanceof ObjectStoredAsAddress) {
-      this.part = ((ObjectStoredAsAddress)so).getRawBytes();
+    if (so.hasRefCount()) {
+      this.part = so;
     } else {
-      this.part = (ObjectStoredInMemory)so;
+      this.part = so.getValueAsHeapByteArray();
     }
   }
   public byte getTypeCode() {
@@ -146,8 +143,8 @@ public class Part {
       return 0;
     } else if (this.part instanceof byte[]) {
       return ((byte[])this.part).length;
-    } else if (this.part instanceof ObjectStoredInMemory) {
-      return ((ObjectStoredInMemory) this.part).getValueSizeInBytes();
+    } else if (this.part instanceof StoredObject) {
+      return ((StoredObject) this.part).getDataSize();
     } else {
       return ((HeapDataOutputStream)this.part).size();
     }
@@ -289,14 +286,14 @@ public class Part {
       if (this.part instanceof byte[]) {
         byte[] bytes = (byte[])this.part;
         out.write(bytes, 0, bytes.length);
-      } else if (this.part instanceof ObjectStoredInMemory) {
-        ObjectStoredInMemory c = (ObjectStoredInMemory) this.part;
-        ByteBuffer cbb = c.createDirectByteBuffer();
-        if (cbb != null) {
-          HeapDataOutputStream.writeByteBufferToStream(out,  buf, cbb);
+      } else if (this.part instanceof StoredObject) {
+        StoredObject so = (StoredObject) this.part;
+        ByteBuffer sobb = so.createDirectByteBuffer();
+        if (sobb != null) {
+          HeapDataOutputStream.writeByteBufferToStream(out,  buf, sobb);
         } else {
-          int bytesToSend = c.getDataSize();
-          long addr = c.getAddressForReading(0, bytesToSend);
+          int bytesToSend = so.getDataSize();
+          long addr = so.getAddressForReadingData(0, bytesToSend);
           while (bytesToSend > 0) {
             if (buf.remaining() == 0) {
               HeapDataOutputStream.flushStream(out,  buf);
@@ -322,14 +319,14 @@ public class Part {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         buf.put((byte[])this.part);
-      } else if (this.part instanceof ObjectStoredInMemory) {
-        ObjectStoredInMemory c = (ObjectStoredInMemory) this.part;
+      } else if (this.part instanceof StoredObject) {
+        StoredObject c = (StoredObject) this.part;
         ByteBuffer bb = c.createDirectByteBuffer();
         if (bb != null) {
           buf.put(bb);
         } else {
           int bytesToSend = c.getDataSize();
-          long addr = c.getAddressForReading(0, bytesToSend);
+          long addr = c.getAddressForReadingData(0, bytesToSend);
           while (bytesToSend > 0) {
             buf.put(AddressableMemoryManager.readByte(addr));
             addr++;
@@ -372,10 +369,10 @@ public class Part {
           }
           buf.clear();
         }
-      } else if (this.part instanceof ObjectStoredInMemory) {
-        // instead of copying the Chunk to buf try to create a direct ByteBuffer and
+      } else if (this.part instanceof StoredObject) {
+        // instead of copying the StoredObject to buf try to create a direct ByteBuffer and
         // just write it directly to the socket channel.
-        ObjectStoredInMemory c = (ObjectStoredInMemory) this.part;
+        StoredObject c = (StoredObject) this.part;
         ByteBuffer bb = c.createDirectByteBuffer();
         if (bb != null) {
           while (bb.remaining() > 0) {
@@ -383,7 +380,7 @@ public class Part {
           }
         } else {
           int len = c.getDataSize();
-          long addr = c.getAddressForReading(0, len);
+          long addr = c.getAddressForReadingData(0, len);
           buf.clear();
           while (len > 0) {
             int bytesThisTime = len;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java
index b87903e..e382c57 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java
@@ -42,7 +42,6 @@ import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
-import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 import com.gemstone.gemfire.internal.security.AuthorizeRequest;
@@ -321,12 +320,13 @@ public class Get70 extends BaseCommand {
     // disk. If it is already a byte[], set isObject to false.
     boolean wasInvalid = false;
     if (data instanceof CachedDeserializable) {
-      if (data instanceof StoredObject && !((StoredObject) data).isSerialized()) {
+      CachedDeserializable cd = (CachedDeserializable) data;
+      if (!cd.isSerialized()) {
         // it is a byte[]
         isObject = false;
-        data = ((StoredObject) data).getDeserializedForReading();
+        data = cd.getDeserializedForReading();
       } else {
-        data = ((CachedDeserializable)data).getValue();
+        data = cd.getValue();
       }
     }
     else if (data == Token.REMOVED_PHASE1 || data == Token.REMOVED_PHASE2 || data == Token.DESTROYED) {
@@ -391,13 +391,10 @@ public class Get70 extends BaseCommand {
     else if (data instanceof byte[]) {
       isObject = false;
     } else if (data instanceof CachedDeserializable) {
-      if (data instanceof StoredObject) {
-        // it is off-heap so do not unwrap it.
-        if (!((StoredObject) data).isSerialized()) {
-          isObject = false;
-        }
-      } else {
-        data = ((CachedDeserializable)data).getValue();
+      CachedDeserializable cd = (CachedDeserializable) data;
+      isObject = cd.isSerialized();
+      if (cd.usesHeapForStorage()) {
+        data = cd.getValue();
       }
     }
     Entry result = new Entry();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Request.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Request.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Request.java
index 6c806c8..b40b6e5 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Request.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Request.java
@@ -38,7 +38,6 @@ import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
 import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
-import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.security.AuthorizeRequest;
 import com.gemstone.gemfire.internal.security.AuthorizeRequestPP;
 import com.gemstone.gemfire.security.NotAuthorizedException;
@@ -253,12 +252,13 @@ public class Request extends BaseCommand {
     // disk. If it is already a byte[], set isObject to false.
     // TODO OFFHEAP: optimize
     if (data instanceof CachedDeserializable) {
-      if (data instanceof StoredObject && !((StoredObject) data).isSerialized()) {
+      CachedDeserializable cd = (CachedDeserializable) data;
+      if (!cd.isSerialized()) {
         // it is a byte[]
         isObject = false;
-        data = ((StoredObject) data).getDeserializedForReading();
+        data = cd.getDeserializedForReading();
       } else {
-        data = ((CachedDeserializable)data).getValue();
+        data = cd.getValue();
       }
     }
     else if (data == Token.REMOVED_PHASE1 || data == Token.REMOVED_PHASE2 || data == Token.TOMBSTONE || data == Token.DESTROYED) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
index 51ee135..1884a14 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/wan/GatewaySenderEventImpl.java
@@ -554,11 +554,11 @@ public class GatewaySenderEventImpl implements
       result = this.substituteValue;
       if (result == null) {
       result = this.valueObj;
-      if (result instanceof ObjectStoredInMemory) {
+      if (result instanceof StoredObject && ((StoredObject) result).hasRefCount()) {
         if (this.valueObjReleased) {
           result = null;
         } else {
-          ObjectStoredInMemory ohref = (ObjectStoredInMemory) result;
+          StoredObject ohref = (StoredObject) result;
           if (!ohref.retain()) {
             result = null;
           } else if (this.valueObjReleased) {
@@ -1280,7 +1280,7 @@ public class GatewaySenderEventImpl implements
           return this;
         }
       }
-      if (v instanceof ObjectStoredInMemory) {
+      if (v instanceof StoredObject && ((StoredObject) v).hasRefCount()) {
         try {
           return makeCopy();
         } catch (IllegalStateException ex) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AbstractStoredObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AbstractStoredObject.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AbstractStoredObject.java
index 6dad277..7a9c5f6 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AbstractStoredObject.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AbstractStoredObject.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 
 import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.DSCODE;
 import com.gemstone.gemfire.internal.DataSerializableFixedID;
 import com.gemstone.gemfire.internal.InternalDataSerializer;
 import com.gemstone.gemfire.internal.cache.RegionEntry;
@@ -104,4 +105,20 @@ public abstract class AbstractStoredObject implements StoredObject {
     InternalDataSerializer.writeDSFIDHeader(DataSerializableFixedID.VM_CACHED_DESERIALIZABLE, out);
     sendAsByteArray(out);
   }
+  
+  @Override
+  public boolean usesHeapForStorage() {
+    return false;
+  }
+  
+  @Override
+  public boolean isSerializedPdxInstance() {
+    if (!isSerialized()) {
+      return false;
+    }
+    // TODO OFFHEAP: what if the data is compressed?
+    byte dsCode = this.readDataByte(0);
+    return dsCode == DSCODE.PDX || dsCode == DSCODE.PDX_ENUM || dsCode == DSCODE.PDX_INLINE_ENUM;
+  }
+  
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryManager.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryManager.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryManager.java
index 0f2d007..3b6f58d 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableMemoryManager.java
@@ -16,6 +16,11 @@
  */
 package com.gemstone.gemfire.internal.offheap;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
 import com.gemstone.gemfire.internal.SharedLibrary;
 import com.gemstone.gemfire.pdx.internal.unsafe.UnsafeWrapper;
 
@@ -151,4 +156,106 @@ public class AddressableMemoryManager {
     unsafe.setMemory(addr, size, fill);
   }
 
+  @SuppressWarnings("rawtypes")
+  private static volatile Class dbbClass = null;
+  @SuppressWarnings("rawtypes")
+  private static volatile Constructor dbbCtor = null;
+  private static volatile boolean dbbCreateFailed = false;
+  private static volatile Method dbbAddressMethod = null;
+  private static volatile boolean dbbAddressFailed = false;
+
+  /**
+   * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer.
+   * If the buffer is not direct or the address can not be obtained return 0.
+   */
+  @SuppressWarnings({ "rawtypes", "unchecked" })
+  public static long getDirectByteBufferAddress(ByteBuffer bb) {
+    if (!bb.isDirect()) {
+      return 0L;
+    }
+    if (dbbAddressFailed) {
+      return 0L;
+    }
+    Method m = dbbAddressMethod;
+    if (m == null) {
+      Class c = dbbClass;
+      if (c == null) {
+        try {
+          c = Class.forName("java.nio.DirectByteBuffer");
+        } catch (ClassNotFoundException e) {
+          //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
+          dbbCreateFailed = true;
+          dbbAddressFailed = true;
+          return 0L;
+        }
+        dbbClass = c;
+      }
+      try {
+        m = c.getDeclaredMethod("address");
+      } catch (NoSuchMethodException | SecurityException e) {
+        //throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
+        dbbClass = null;
+        dbbAddressFailed = true;
+        return 0L;
+      }
+      m.setAccessible(true);
+      dbbAddressMethod = m;
+    }
+    try {
+      return (Long)m.invoke(bb);
+    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+      //throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()", e);
+      dbbClass = null;
+      dbbAddressMethod = null;
+      dbbAddressFailed = true;
+      return 0L;
+    }
+  }
+
+  /**
+   * Create a direct byte buffer given its address and size.
+   * The returned ByteBuffer will be direct and use the memory at the given address.
+   * @return the created direct byte buffer or null if it could not be created.
+   */
+  @SuppressWarnings({ "rawtypes", "unchecked" })
+  static ByteBuffer createDirectByteBuffer(long address, int size) {
+    if (dbbCreateFailed) {
+      return null;
+    }
+    Constructor ctor = dbbCtor;
+    if (ctor == null) {
+      Class c = dbbClass;
+      if (c == null) {
+        try {
+          c = Class.forName("java.nio.DirectByteBuffer");
+        } catch (ClassNotFoundException e) {
+          //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
+          dbbCreateFailed = true;
+          dbbAddressFailed = true;
+          return null;
+        }
+        dbbClass = c;
+      }
+      try {
+        ctor = c.getDeclaredConstructor(long.class, int.class);
+      } catch (NoSuchMethodException | SecurityException e) {
+        //throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)", e);
+        dbbClass = null;
+        dbbCreateFailed = true;
+        return null;
+      }
+      ctor.setAccessible(true);
+      dbbCtor = ctor;
+    }
+    try {
+      return (ByteBuffer)ctor.newInstance(address, size);
+    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+      //throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long, int)", e);
+      dbbClass = null;
+      dbbCtor = null;
+      dbbCreateFailed = true;
+      return null;
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableStoredObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableStoredObject.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableStoredObject.java
deleted file mode 100644
index 666070c..0000000
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/AddressableStoredObject.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gemstone.gemfire.internal.offheap;
-
-import java.nio.ByteBuffer;
-
-import com.gemstone.gemfire.internal.offheap.annotations.Retained;
-import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
-
-/**
- * Represents a stored object whose stored data is also addressable.
- * This interface provides methods that let you read and write the bytes
- * of addressable memory used to store the bytes of the object.
- * A reference count is used to determine if the object is still allocated.
- * To increment the count call {@link #retain()}.
- * To decrement the count call {@link #release()}.
- * 
- * @author darrel
- * @since 9.0
- */
-public interface AddressableStoredObject extends StoredObject, Releasable {
-  
-  /**
-   * Returns the address of the memory used to store this object.
-   * This address may not be to the first byte of stored data since
-   * the implementation may store some internal data in the first bytes of the memory.
-   * This address can be used with AddressableMemoryManager.
-   */
-  public long getMemoryAddress();
-  /**
-   * Returns the number of bytes of memory used by this object to store an object.
-   * This size includes any bytes used for padding and meta-information.
-   */
-  public int getSize();
-  
-  /**
-   * Returns the address of the first byte of memory used to store this object.
-   * This address will not be to any padding or meta-data bytes that precede the
-   * first data byte.
-   * This address can be used with AddressableMemoryManager.
-   */
-  public long getDataAddress();
-  /**
-   * Returns the number of bytes of memory used to store the object.
-   * This size does not include any bytes used for padding.
-   */
-  public int getDataSize();
-
-  public byte readDataByte(int offset);
-  public void writeDataByte(int offset, byte value);
-  
-  public void readDataBytes(int offset, byte[] bytes);
-  public void writeDataBytes(int offset, byte[] bytes);
-  public void readDataBytes(int offset, byte[] bytes, int bytesOffset, int size);
-  public void writeDataBytes(int offset, byte[] bytes, int bytesOffset, int size);
-  /**
-   * Creates and returns a direct ByteBuffer that contains the data of this stored object.
-   * Note that the returned ByteBuffer has a reference to the
-   * address of this stored object so it can only be used while this stored object is retained.
-   * @return the created direct byte buffer or null if it could not be created.
-   */
-  @Unretained
-  public ByteBuffer createDirectByteBuffer();
-
-  
-  /**
-   * Call to indicate that this object's memory is in use by the caller.
-   * The memory will stay allocated until {@link #release()} is called.
-   * It is ok for a thread other than the one that called this method to call release.
-   * This method is called implicitly at the time the chunk is allocated.
-   * Note: @Retained tells you that "this" is retained by this method.
-   * 
-   * @throws IllegalStateException if the max ref count is exceeded.
-   * @return true if we are able to retain this chunk; false if we need to retry
-   */
-  @Retained
-  public boolean retain();
-
-   /**
-   * Returns the number of users of this memory.
-   */
-  public int getRefCount();
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
index 00501cf..0b25104 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/Fragment.java
@@ -60,7 +60,7 @@ public class Fragment implements MemoryBlock {
     return this.size;
   }
 
-  public long getMemoryAddress() {
+  public long getAddress() {
     return this.baseAddr;
   }
 
@@ -121,14 +121,14 @@ public class Fragment implements MemoryBlock {
   @Override
   public boolean equals(Object o) {
     if (o instanceof Fragment) {
-      return getMemoryAddress() == ((Fragment) o).getMemoryAddress();
+      return getAddress() == ((Fragment) o).getAddress();
     }
     return false;
   }
   
   @Override
   public int hashCode() {
-    long value = this.getMemoryAddress();
+    long value = this.getAddress();
     return (int)(value ^ (value >>> 32));
   }
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
index 7d927b0..728764b 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
@@ -63,7 +63,7 @@ public class FreeListManager {
     while (addr <= (slab.getMemoryAddress() + slab.getSize() - ObjectStoredInMemory.MIN_CHUNK_SIZE)) {
       Fragment f = isAddrInFragmentFreeSpace(addr);
       if (f != null) {
-        addr = f.getMemoryAddress() + f.getSize();
+        addr = f.getAddress() + f.getSize();
       } else {
         int curChunkSize = ObjectStoredInMemory.getSize(addr);
         int refCount = ObjectStoredInMemory.getRefCount(addr);
@@ -79,7 +79,7 @@ public class FreeListManager {
    */
   private Fragment isAddrInFragmentFreeSpace(long addr) {
     for (Fragment f: this.fragmentList) {
-      if (addr >= (f.getMemoryAddress() + f.getFreeIndex()) && addr < (f.getMemoryAddress() + f.getSize())) {
+      if (addr >= (f.getAddress() + f.getFreeIndex()) && addr < (f.getAddress() + f.getSize())) {
         return f;
       }
     }
@@ -263,7 +263,7 @@ public class FreeListManager {
     for (Fragment f: this.fragmentList) {
       int freeSpace = f.freeSpace();
       if (freeSpace > 0) {
-        lw.info("Fragment at " + f.getMemoryAddress() + " of size " + f.getSize() + " has " + freeSpace + " bytes free.");
+        lw.info("Fragment at " + f.getAddress() + " of size " + f.getSize() + " has " + freeSpace + " bytes free.");
       }
     }
   }
@@ -526,7 +526,7 @@ public class FreeListManager {
         // The current fragment is completely allocated so just skip it.
         continue;
       }
-      long chunkAddr = f.getMemoryAddress()+offset;
+      long chunkAddr = f.getAddress()+offset;
       ObjectStoredInMemory.setSize(chunkAddr, diff);
       result.offer(chunkAddr);
     }
@@ -556,7 +556,7 @@ public class FreeListManager {
         result = new SyncChunkStack();
         l.add(result);
       }
-      result.offer(c.getMemoryAddress());
+      result.offer(c.getAddress());
       c = this.hugeChunkSet.pollFirst();
     }
   }
@@ -591,7 +591,7 @@ public class FreeListManager {
         if (fragment.allocate(oldOffset, newOffset)) {
           // We did the allocate!
           this.lastFragmentAllocation.set(fragIdx);
-          ObjectStoredInMemory result = new ObjectStoredInMemory(fragment.getMemoryAddress()+oldOffset, chunkSize+extraSize);
+          ObjectStoredInMemory result = new ObjectStoredInMemory(fragment.getAddress()+oldOffset, chunkSize+extraSize);
           checkDataIntegrity(result);
           return result;
         } else {
@@ -737,7 +737,7 @@ public class FreeListManager {
         new Comparator<MemoryBlock>() {
           @Override
           public int compare(MemoryBlock o1, MemoryBlock o2) {
-            return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+            return Long.valueOf(o1.getAddress()).compareTo(o2.getAddress());
           }
     });
     return value;
@@ -780,7 +780,7 @@ public class FreeListManager {
         new Comparator<MemoryBlock>() {
           @Override
           public int compare(MemoryBlock o1, MemoryBlock o2) {
-            return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+            return Long.valueOf(o1.getAddress()).compareTo(o2.getAddress());
           }
     });
     return value;
@@ -803,7 +803,7 @@ public class FreeListManager {
     }
 
     @Override
-    public long getMemoryAddress() {
+    public long getAddress() {
       return address;
     }
 
@@ -855,14 +855,14 @@ public class FreeListManager {
     @Override
     public boolean equals(Object o) {
       if (o instanceof TinyMemoryBlock) {
-        return getMemoryAddress() == ((TinyMemoryBlock) o).getMemoryAddress();
+        return getAddress() == ((TinyMemoryBlock) o).getAddress();
       }
       return false;
     }
     
     @Override
     public int hashCode() {
-      long value = this.getMemoryAddress();
+      long value = this.getAddress();
       return (int)(value ^ (value >>> 32));
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
index 039ca2e..0f776e7 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryAllocator.java
@@ -29,18 +29,30 @@ public interface MemoryAllocator {
    * @return the allocated chunk of memory.
    * @throws IllegalStateException if the heap does not have enough memory to grant the request
    */
-  public AddressableStoredObject allocate(int size);
+  public StoredObject allocate(int size);
   
   /**
-   * Allocates off heap memory for the given data and returns a MemoryChunk
+   * Allocates off heap memory for the given data and returns a StoredObject
    * that is backed by this allocated memory and that contains the data.
-   * @param data the bytes of the data to put in the allocated CachedDeserializable
+   * @param data the bytes of the data to put in the allocated StoredObject
    * @param isSerialized true if data contains a serialized object; false if it is an actual byte array.
    * @param isCompressed true if data is compressed; false if it is uncompressed.
    * @throws IllegalStateException if the heap does not have enough memory to grant the request
    */
   public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed);
   
+  /**
+   * Allocates off heap memory for the given data and returns a StoredObject
+   * that is backed by this allocated memory and that contains the data
+   * and keeps a reference to the original heap data.
+   * @param data the bytes of the data to put in the allocated StoredObject
+   * @param isSerialized true if data contains a serialized object; false if it is an actual byte array.
+   * @param originalHeapData the original uncompressed heap data
+   * @param isCompressed true if data is compressed; false if it is uncompressed.
+   * @throws IllegalStateException if the heap does not have enough memory to grant the request
+   */
+  public StoredObject allocateAndInitialize(byte[] data, boolean isSerialized, boolean isCompressed, byte[] originalHeapData);
+  
   public long getFreeMemory();
   
   public long getUsedMemory();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
index d8cb80a..878d06f 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlock.java
@@ -40,7 +40,7 @@ public interface MemoryBlock {
   /**
    * Returns the unsafe memory address of the first byte of this block.
    */
-  public long getMemoryAddress();
+  public long getAddress();
   
   /**
    * Returns the size of this memory block in bytes.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
index 3e5186f..92cf5e2 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/MemoryBlockNode.java
@@ -37,8 +37,8 @@ public class MemoryBlockNode implements MemoryBlock {
     return this.block.getState();
   }
   @Override
-  public long getMemoryAddress() {
-    return this.block.getMemoryAddress();
+  public long getAddress() {
+    return this.block.getAddress();
   }
   @Override
   public int getBlockSize() {
@@ -49,7 +49,7 @@ public class MemoryBlockNode implements MemoryBlock {
     return this.ma.getMemoryInspector().getBlockAfter(this);
   }
   public int getSlabId() {
-    return this.ma.findSlab(getMemoryAddress());
+    return this.ma.findSlab(getAddress());
   }
   @Override
   public int getFreeListId() {
@@ -113,7 +113,7 @@ public class MemoryBlockNode implements MemoryBlock {
   public String toString() {
     final StringBuilder sb = new StringBuilder(MemoryBlock.class.getSimpleName());
     sb.append("{");
-    sb.append("MemoryAddress=").append(getMemoryAddress());
+    sb.append("MemoryAddress=").append(getAddress());
     sb.append(", State=").append(getState());
     sb.append(", BlockSize=").append(getBlockSize());
     sb.append(", SlabId=").append(getSlabId());

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredAsAddress.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredAsAddress.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredAsAddress.java
index d4f59d0..8fc2bb2 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredAsAddress.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredAsAddress.java
@@ -16,6 +16,9 @@
  */
 package com.gemstone.gemfire.internal.offheap;
 
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
 import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
 import com.gemstone.gemfire.internal.cache.EntryBits;
@@ -43,21 +46,25 @@ public class ObjectStoredAsAddress extends AbstractStoredObject {
     this.address = addr;
   }
   
-  public long getEncodedAddress() {
+  @Override
+  public long getAddress() {
     return this.address;
   }
 
   @Override
   public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
     if (o instanceof ObjectStoredAsAddress) {
-      return getEncodedAddress() == ((ObjectStoredAsAddress) o).getEncodedAddress();
+      return getAddress() == ((ObjectStoredAsAddress) o).getAddress();
     }
     return false;
   }
   
   @Override
   public int hashCode() {
-    long value = getEncodedAddress();
+    long value = getAddress();
     return (int)(value ^ (value >>> 32));
   }
 
@@ -67,7 +74,7 @@ public class ObjectStoredAsAddress extends AbstractStoredObject {
   }
 
   public byte[] getDecompressedBytes(RegionEntryContext r) {
-    byte[] bytes = OffHeapRegionEntryHelper.decodeAddressToBytes(getEncodedAddress(), true, true);
+    byte[] bytes = OffHeapRegionEntryHelper.decodeAddressToBytes(getAddress(), true, true);
     if (isCompressed()) {
         long time = r.getCachePerfStats().startDecompression();
         bytes = r.getCompressor().decompress(bytes);
@@ -81,7 +88,7 @@ public class ObjectStoredAsAddress extends AbstractStoredObject {
    * Otherwise return the serialize bytes in us in a byte array.
    */
   public byte[] getRawBytes() {
-    return OffHeapRegionEntryHelper.decodeAddressToBytes(getEncodedAddress(), true, false);
+    return OffHeapRegionEntryHelper.decodeAddressToBytes(getAddress(), true, false);
   }
   
   @Override
@@ -125,4 +132,98 @@ public class ObjectStoredAsAddress extends AbstractStoredObject {
   public boolean isCompressed() {
     return OffHeapRegionEntryHelper.isCompressed(this.address);
   }
+
+  @Override
+  public void release() {
+    // nothing needed
+  }
+
+  @Override
+  public boolean retain() {
+    return true;
+  }
+
+  @Override
+  public int getRefCount() {
+    return -1;
+  }
+
+  @Override
+  public int getSize() {
+    return Long.BYTES;
+  }
+
+  @Override
+  public int getDataSize() {
+    return OffHeapRegionEntryHelper.decodeAddressToDataSize(this.address);
+  }
+
+  @Override
+  public byte readDataByte(int offset) {
+    // TODO OFFHEAP: what if the data is compressed?
+    return getRawBytes()[offset];
+  }
+
+  @Override
+  public void writeDataByte(int offset, byte value) {
+    throw new UnsupportedOperationException("ObjectStoredAsAddress does not support modifying the data bytes");
+  }
+
+  @Override
+  public void readDataBytes(int offset, byte[] bytes) {
+    readDataBytes(offset, bytes, 0, bytes.length);
+  }
+
+  @Override
+  public void writeDataBytes(int offset, byte[] bytes) {
+    writeDataBytes(offset, bytes, 0, bytes.length);
+  }
+
+  @Override
+  public void readDataBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+    // TODO OFFHEAP: what if the data is compressed?
+    byte[] src = getRawBytes();
+    int dstIdx = bytesOffset;
+    for (int i = offset; i < offset+size; i++) {
+      bytes[dstIdx++] = src[i];
+    }
+  }
+
+  @Override
+  public void writeDataBytes(int offset, byte[] bytes, int bytesOffset, int size) {
+    throw new UnsupportedOperationException("ObjectStoredAsAddress does not support modifying the data bytes");
+  }
+
+  @Override
+  public ByteBuffer createDirectByteBuffer() {
+    return null;
+  }
+
+  @Override
+  public boolean hasRefCount() {
+    return false;
+  }
+
+  @Override
+  public boolean checkDataEquals(StoredObject so) {
+    // TODO OFFHEAP: what if the data is compressed?
+    return equals(so);
+  }
+
+  @Override
+  public boolean checkDataEquals(byte[] serializedObj) {
+    // TODO OFFHEAP: what if the data is compressed?
+    byte[] myBytes = getSerializedValue();
+    return Arrays.equals(myBytes, serializedObj);
+  }
+
+  @Override
+  public long getAddressForReadingData(int offset, int size) {
+    throw new UnsupportedOperationException("ObjectStoredAsAddress does not support reading at an address");
+  }
+
+  @Override
+  public StoredObject slice(int offset, int limit) {
+    throw new UnsupportedOperationException("ObjectStoredAsAddress does not support slice");
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredInMemory.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredInMemory.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredInMemory.java
index aa5da80..7de4f37 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredInMemory.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectStoredInMemory.java
@@ -18,9 +18,6 @@ package com.gemstone.gemfire.internal.offheap;
 
 import java.io.DataOutput;
 import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 
 import com.gemstone.gemfire.cache.Region;
@@ -45,7 +42,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
    * to it in the cache. Instead the memoryAddress is stored in a primitive field in
    * the cache and if used it will then, if needed, create an instance of this class.
    */
-  public class ObjectStoredInMemory extends AbstractStoredObject implements AddressableStoredObject, Comparable<ObjectStoredInMemory>, MemoryBlock {
+  public class ObjectStoredInMemory extends AbstractStoredObject implements Comparable<ObjectStoredInMemory>, MemoryBlock {
     /**
      * The unsafe memory address of the first byte of this chunk
      */
@@ -102,14 +99,14 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       SimpleMemoryAllocatorImpl.validateAddressAndSize(memoryAddress, chunkSize);
       this.memoryAddress = memoryAddress;
       setSize(chunkSize);
-      AddressableMemoryManager.writeIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, MAGIC_NUMBER);
+      AddressableMemoryManager.writeIntVolatile(getAddress()+REF_COUNT_OFFSET, MAGIC_NUMBER);
     }
     public void readyForFree() {
-      AddressableMemoryManager.writeIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0);
+      AddressableMemoryManager.writeIntVolatile(getAddress()+REF_COUNT_OFFSET, 0);
     }
     public void readyForAllocation() {
-      if (!AddressableMemoryManager.writeIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET, 0, MAGIC_NUMBER)) {
-        throw new IllegalStateException("Expected 0 but found " + Integer.toHexString(AddressableMemoryManager.readIntVolatile(getMemoryAddress()+REF_COUNT_OFFSET)));
+      if (!AddressableMemoryManager.writeIntVolatile(getAddress()+REF_COUNT_OFFSET, 0, MAGIC_NUMBER)) {
+        throw new IllegalStateException("Expected 0 but found " + Integer.toHexString(AddressableMemoryManager.readIntVolatile(getAddress()+REF_COUNT_OFFSET)));
       }
     }
     /**
@@ -137,7 +134,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       if (isSerialized()) {
         userBits = EntryBits.setSerialized(userBits, true);
       }
-      wrapper.setChunkData((ObjectStoredInMemory) this, userBits);
+      wrapper.setOffHeapData(this, userBits);
     }
     
     String getShortClassName() {
@@ -145,17 +142,25 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       return cname.substring(getClass().getPackage().getName().length()+1);
     }
 
-    public boolean checkDataEquals(@Unretained ObjectStoredInMemory other) {
-      if (this == other) {
+    @Override
+    public boolean checkDataEquals(@Unretained StoredObject so) {
+      if (this == so) {
         return true;
       }
-      if (isSerialized() != other.isSerialized()) {
+      if (isSerialized() != so.isSerialized()) {
         return false;
       }
       int mySize = getValueSizeInBytes();
-      if (mySize != other.getValueSizeInBytes()) {
+      if (mySize != so.getValueSizeInBytes()) {
+        return false;
+      }
+      if (!(so instanceof ObjectStoredInMemory)) {
         return false;
       }
+      ObjectStoredInMemory other = (ObjectStoredInMemory) so;
+      if (getAddress() == other.getAddress()) {
+        return true;
+      }
       // We want to be able to do this operation without copying any of the data into the heap.
       // Hopefully the jvm is smart enough to use our stack for this short lived array.
       final byte[] dataCache1 = new byte[1024];
@@ -188,11 +193,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       return true;
     }
     
-    public boolean isSerializedPdxInstance() {
-      byte dsCode = this.readDataByte(0);
-      return dsCode == DSCODE.PDX || dsCode == DSCODE.PDX_ENUM || dsCode == DSCODE.PDX_INLINE_ENUM;
-    }
-    
+    @Override
     public boolean checkDataEquals(byte[] serializedObj) {
       // caller was responsible for checking isSerialized
       int mySize = getValueSizeInBytes();
@@ -256,15 +257,11 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     }
 
     @Override
-    public long getMemoryAddress() {
+    public long getAddress() {
       return this.memoryAddress;
     }
     
     @Override
-    public long getDataAddress() {
-      return getBaseDataAddress();
-    }
-    @Override
     public int getDataSize() {
       return getDataSize(this.memoryAddress);
     }
@@ -286,7 +283,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     @Override
     @Unretained
     public ByteBuffer createDirectByteBuffer() {
-      return basicCreateDirectByteBuffer(getBaseDataAddress(), getDataSize());
+      return AddressableMemoryManager.createDirectByteBuffer(getBaseDataAddress(), getDataSize());
     }
     @Override
     public void sendTo(DataOutput out) throws IOException {
@@ -321,101 +318,6 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       super.sendAsByteArray(out);
     }
        
-    private static volatile Class dbbClass = null;
-    private static volatile Constructor dbbCtor = null;
-    private static volatile boolean dbbCreateFailed = false;
-    
-    /**
-     * @return the created direct byte buffer or null if it could not be created.
-     */
-    private static ByteBuffer basicCreateDirectByteBuffer(long baseDataAddress, int dataSize) {
-      if (dbbCreateFailed) {
-        return null;
-      }
-      Constructor ctor = dbbCtor;
-      if (ctor == null) {
-        Class c = dbbClass;
-        if (c == null) {
-          try {
-            c = Class.forName("java.nio.DirectByteBuffer");
-          } catch (ClassNotFoundException e) {
-            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
-            dbbCreateFailed = true;
-            dbbAddressFailed = true;
-            return null;
-          }
-          dbbClass = c;
-        }
-        try {
-          ctor = c.getDeclaredConstructor(long.class, int.class);
-        } catch (NoSuchMethodException | SecurityException e) {
-          //throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)", e);
-          dbbClass = null;
-          dbbCreateFailed = true;
-          return null;
-        }
-        ctor.setAccessible(true);
-        dbbCtor = ctor;
-      }
-      try {
-        return (ByteBuffer)ctor.newInstance(baseDataAddress, dataSize);
-      } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        //throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long, int)", e);
-        dbbClass = null;
-        dbbCtor = null;
-        dbbCreateFailed = true;
-        return null;
-      }
-    }
-    private static volatile Method dbbAddressMethod = null;
-    private static volatile boolean dbbAddressFailed = false;
-    
-    /**
-     * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer.
-     * If the buffer is not direct or the address can not be obtained return 0.
-     */
-    public static long getDirectByteBufferAddress(ByteBuffer bb) {
-      if (!bb.isDirect()) {
-        return 0L;
-      }
-      if (dbbAddressFailed) {
-        return 0L;
-      }
-      Method m = dbbAddressMethod;
-      if (m == null) {
-        Class c = dbbClass;
-        if (c == null) {
-          try {
-            c = Class.forName("java.nio.DirectByteBuffer");
-          } catch (ClassNotFoundException e) {
-            //throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
-            dbbCreateFailed = true;
-            dbbAddressFailed = true;
-            return 0L;
-          }
-          dbbClass = c;
-        }
-        try {
-          m = c.getDeclaredMethod("address");
-        } catch (NoSuchMethodException | SecurityException e) {
-          //throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
-          dbbClass = null;
-          dbbAddressFailed = true;
-          return 0L;
-        }
-        m.setAccessible(true);
-        dbbAddressMethod = m;
-      }
-      try {
-        return (Long)m.invoke(bb);
-      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        //throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()", e);
-        dbbClass = null;
-        dbbAddressMethod = null;
-        dbbAddressFailed = true;
-        return 0L;
-      }
-    }
     /**
      * Returns an address that can be used with unsafe apis to access this chunks memory.
      * @param offset the offset from this chunk's first byte of the byte the returned address should point to. Must be >= 0.
@@ -452,8 +354,8 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       writeDataBytes(offset, bytes, 0, bytes.length);
     }
 
-    public long getAddressForReading(int offset, int size) {
-      //delegate to getUnsafeAddress - as both the methods does return the memory address from given offset
+    @Override
+    public long getAddressForReadingData(int offset, int size) {
       return getUnsafeAddress(offset, size);
     }
     
@@ -480,7 +382,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       if (result == 0) {
         // For the same sized chunks we really don't care about their order
         // but we need compareTo to only return 0 if the two chunks are identical
-        result = Long.signum(getMemoryAddress() - o.getMemoryAddress());
+        result = Long.signum(getAddress() - o.getAddress());
       }
       return result;
     }
@@ -488,14 +390,14 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     @Override
     public boolean equals(Object o) {
       if (o instanceof ObjectStoredInMemory) {
-        return getMemoryAddress() == ((ObjectStoredInMemory) o).getMemoryAddress();
+        return getAddress() == ((ObjectStoredInMemory) o).getAddress();
       }
       return false;
     }
     
     @Override
     public int hashCode() {
-      long value = this.getMemoryAddress();
+      long value = this.getAddress();
       return (int)(value ^ (value >>> 32));
     }
 
@@ -624,12 +526,12 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     public void validateFill() {
       assert FreeListManager.TINY_MULTIPLE == 8;
       
-      long startAddress = getMemoryAddress() + MIN_CHUNK_SIZE;
+      long startAddress = getAddress() + MIN_CHUNK_SIZE;
       int size = getSize() - MIN_CHUNK_SIZE;
       
       for(int i = 0;i < size;i += FreeListManager.TINY_MULTIPLE) {
         if(AddressableMemoryManager.readLong(startAddress + i) != FILL_PATTERN) {
-          throw new IllegalStateException("Fill pattern violated for chunk " + getMemoryAddress() + " with size " + getSize());
+          throw new IllegalStateException("Fill pattern violated for chunk " + getAddress() + " with size " + getSize());
         }        
       }
     }
@@ -775,7 +677,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     
     @Override
     public String toString() {
-      return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getMemoryAddress()) + ">";
+      return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getAddress()) + ">";
     }
     
     @Override
@@ -810,7 +712,11 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
     public Object getDataValue() {
       return null;
     }
-    public ObjectStoredInMemory slice(int position, int limit) {
+    public StoredObject slice(int position, int limit) {
       return new ObjectChunkSlice(this, position, limit);
     }
+    @Override
+    public boolean hasRefCount() {
+      return true;
+    }
   }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapHelper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapHelper.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapHelper.java
index 50944ac..8989293 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapHelper.java
@@ -93,8 +93,8 @@ public class OffHeapHelper {
    * @return true if release was done
    */
   public static boolean release(@Released Object o) {
-    if (o instanceof AddressableStoredObject) {
-      ((AddressableStoredObject) o).release();
+    if (o instanceof StoredObject) {
+      ((StoredObject) o).release();
       return true;
     } else {
       return false;
@@ -105,9 +105,14 @@ public class OffHeapHelper {
    * @return true if release was done
    */
   public static boolean releaseWithNoTracking(@Released Object o) {
-    if (o instanceof AddressableStoredObject) {
+    if (o instanceof StoredObject) {
+      StoredObject so = (StoredObject) o;
+      if (!so.hasRefCount()) {
+        so.release();
+        return true;
+      }
       ReferenceCountHelper.skipRefCountTracking();
-      ((AddressableStoredObject) o).release();
+      so.release();
       ReferenceCountHelper.unskipRefCountTracking();
       return true;
     } else {
@@ -120,9 +125,14 @@ public class OffHeapHelper {
    * @return true if release was done
    */
   public static boolean releaseAndTrackOwner(@Released final Object o, final Object owner) {
-    if (o instanceof AddressableStoredObject) {
+    if (o instanceof StoredObject) {
+      StoredObject so = (StoredObject) o;
+      if (!so.hasRefCount()) {
+        so.release();
+        return true;
+      }
       ReferenceCountHelper.setReferenceCountOwner(owner);
-      ((AddressableStoredObject) o).release();
+      so.release();
       ReferenceCountHelper.setReferenceCountOwner(null);
       return true;
     } else {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
index 8174902..273b550 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapRegionEntryHelper.java
@@ -63,8 +63,7 @@ public class OffHeapRegionEntryHelper {
   };
   
   private static long objectToAddress(@Unretained Object v) {
-    if (v instanceof ObjectStoredInMemory) return ((ObjectStoredInMemory) v).getMemoryAddress();
-    if (v instanceof ObjectStoredAsAddress) return ((ObjectStoredAsAddress) v).getEncodedAddress();
+    if (v instanceof StoredObject) return ((StoredObject) v).getAddress();
     if (v == null) return NULL_ADDRESS;
     if (v == Token.TOMBSTONE) return TOMBSTONE_ADDRESS;
     if (v == Token.INVALID) return INVALID_ADDRESS;
@@ -132,7 +131,7 @@ public class OffHeapRegionEntryHelper {
   }
   
   public static int getSerializedLengthFromDataAsAddress(ObjectStoredAsAddress dataAsAddress) {
-    final long ohAddress = dataAsAddress.getEncodedAddress();
+    final long ohAddress = dataAsAddress.getAddress();
     
      if ((ohAddress & ENCODED_BIT) != 0) {     
       boolean isLong = (ohAddress & LONG_BIT) != 0;     
@@ -184,7 +183,7 @@ public class OffHeapRegionEntryHelper {
     setValue(re, Token.REMOVED_PHASE2);
   }
 
-  public static void releaseEntry(@Unretained OffHeapRegionEntry re, @Released AddressableStoredObject expectedValue) {
+  public static void releaseEntry(@Unretained OffHeapRegionEntry re, @Released StoredObject expectedValue) {
     long oldAddress = objectToAddress(expectedValue);
     final long newAddress = objectToAddress(Token.REMOVED_PHASE2);
     if (re.setAddress(oldAddress, newAddress) || re.getAddress() != newAddress) {
@@ -273,6 +272,15 @@ public class OffHeapRegionEntryHelper {
       }
   }
 
+  static int decodeAddressToDataSize(long addr) {
+    assert (addr & ENCODED_BIT) != 0;
+    boolean isLong = (addr & LONG_BIT) != 0;
+    if (isLong) {
+      return 9;
+    }
+    return (int) ((addr & SIZE_MASK) >> SIZE_SHIFT);
+  }
+  
   static byte[] decodeAddressToBytes(long addr, boolean decompress, boolean compressedOk) {
     assert (addr & ENCODED_BIT) != 0;
     boolean isCompressed = (addr & COMPRESSED_BIT) != 0;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
index ab19a5f..24a57b4 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
@@ -301,13 +301,13 @@ public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     stats.incFreeMemory(-resultSize);
     notifyListeners();
     if (ReferenceCountHelper.trackReferenceCounts()) {
-      ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
+      ReferenceCountHelper.refCountChanged(result.getAddress(), false, 1);
     }
     return result;
   }
   
   @Override
-  public AddressableStoredObject allocate(int size) {
+  public StoredObject allocate(int size) {
     //System.out.println("allocating " + size);
     ObjectStoredInMemory result = allocateChunk(size);
     //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
@@ -324,6 +324,10 @@ public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   
   @Override
   public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed) {
+    return allocateAndInitialize(v, isSerialized, isCompressed, null);
+  }
+  @Override
+  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, byte[] originalHeapData) {
     long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed);
     if (addr != 0L) {
       return new ObjectStoredAsAddress(addr);
@@ -334,6 +338,9 @@ public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     result.setSerializedValue(v);
     result.setSerialized(isSerialized);
     result.setCompressed(isCompressed);
+    if (originalHeapData != null) {
+      result = new ObjectChunkWithHeapForm(result, originalHeapData);
+    }
     return result;
   }
   
@@ -496,7 +503,7 @@ public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         new Comparator<MemoryBlock>() {
           @Override
           public int compare(MemoryBlock o1, MemoryBlock o2) {
-            return Long.valueOf(o1.getMemoryAddress()).compareTo(o2.getMemoryAddress());
+            return Long.valueOf(o1.getAddress()).compareTo(o2.getAddress());
           }
         });
     //this.memoryBlocks = new WeakReference<List<MemoryBlock>>(orphans);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/StoredObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/StoredObject.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/StoredObject.java
index be8ba65..af31134 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/StoredObject.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/StoredObject.java
@@ -18,25 +18,27 @@ package com.gemstone.gemfire.internal.offheap;
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.nio.ByteBuffer;
 
 import com.gemstone.gemfire.internal.Sendable;
 import com.gemstone.gemfire.internal.cache.CachedDeserializable;
 import com.gemstone.gemfire.internal.offheap.annotations.Retained;
+import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 
 /**
  * Represents an object stored in the cache.
  * Currently this interface is only used for values stored in off-heap regions.
+ * This interface provides methods that let you read and write the bytes
+ * of addressable memory used to store the bytes of the object.
+ * A reference count is used to determine if the object is still allocated.
+ * To increment the count call {@link #retain()}.
+ * To decrement the count call {@link #release()}.
  * At some point in the future it may also be used for values stored in heap regions. 
  * 
  * @author darrel
  * @since 9.0
  */
-public interface StoredObject extends Sendable, CachedDeserializable {
- /**
-   * Returns true if the value stored in this memory chunk is a serialized object. Returns false if it is a byte array.
-   */
-  public boolean isSerialized();
-
+public interface StoredObject extends Sendable, CachedDeserializable, Releasable {
   /**
    * Returns true if the value stored in this memory chunk is compressed. Returns false if it is uncompressed.
    */
@@ -79,4 +81,85 @@ public interface StoredObject extends Sendable, CachedDeserializable {
    * @throws IOException
    */
   void sendAsCachedDeserializable(DataOutput out) throws IOException;
+  
+  /**
+   * Call to indicate that this object's memory is in use by the caller.
+   * The memory will stay allocated until {@link #release()} is called.
+   * It is ok for a thread other than the one that called this method to call release.
+   * This method is called implicitly at the time the chunk is allocated.
+   * Note: @Retained tells you that "this" is retained by this method.
+   * 
+   * @throws IllegalStateException if the max ref count is exceeded.
+   * @return true if we are able to retain this chunk; false if we need to retry
+   */
+  @Retained
+  public boolean retain();
+
+  /**
+   * Returns true if this type of StoredObject uses a references count; false otherwise.
+   */
+  public boolean hasRefCount();
+   /**
+   * Returns the number of users of this memory. If this type of StoredObject does not
+   * have a reference count then -1 is returned.
+   */
+  public int getRefCount();
+  
+  /**
+   * Returns the address of the memory used to store this object.
+   * This address may not be to the first byte of stored data since
+   * the implementation may store some internal data in the first bytes of the memory.
+   * This address can be used with AddressableMemoryManager.
+   */
+  public long getAddress();
+
+  /**
+   * Returns the number of bytes of memory used by this object to store an object.
+   * This size includes any bytes used for padding and meta-information.
+   */
+  public int getSize();
+  
+  /**
+   * Returns the number of bytes of memory used to store the object.
+   * This size does not include any bytes used for padding.
+   */
+  public int getDataSize();
+  public byte readDataByte(int offset);
+  public void writeDataByte(int offset, byte value);
+  public void readDataBytes(int offset, byte[] bytes);
+  public void writeDataBytes(int offset, byte[] bytes);
+  public void readDataBytes(int offset, byte[] bytes, int bytesOffset, int size);
+  public void writeDataBytes(int offset, byte[] bytes, int bytesOffset, int size);
+  /**
+   * Returns an address that can read data from this StoredObject at the given offset.
+   */
+  public long getAddressForReadingData(int offset, int size);
+  
+  /**
+   * Returns a StoredObject that acts as if its data is our data starting
+   * at the given offset and limited to the given number of bytes.
+   */
+  public StoredObject slice(int offset, int limit);
+  
+  /**
+   * Returns true if our data is equal to other's data; false otherwise.
+   */
+  public boolean checkDataEquals(StoredObject other);
+  /**
+   * Returns true if the given bytes are equal to our data bytes; false otherwise
+   */
+  public boolean checkDataEquals(byte[] serializedObj);
+
+  /**
+   * Creates and returns a direct ByteBuffer that contains the data of this stored object.
+   * Note that the returned ByteBuffer has a reference to the
+   * address of this stored object so it can only be used while this stored object is retained.
+   * @return the created direct byte buffer or null if it could not be created.
+   */
+  @Unretained
+  public ByteBuffer createDirectByteBuffer();
+  /**
+   * Returns true if the data is serialized with PDX
+   */
+  public boolean isSerializedPdxInstance();
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
index 1179e44..d7ec947 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
@@ -32,7 +32,7 @@ import java.nio.ByteOrder;
 import com.gemstone.gemfire.internal.ByteBufferWriter;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.offheap.AddressableMemoryManager;
-import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 
 /**
  * <p>
@@ -109,15 +109,15 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     public static ByteSource create(ByteBuffer bb) {
       return new ByteBufferByteSource(bb);
     }
-    public static ByteSource create(ObjectStoredInMemory chunk) {
-      // Since I found a way to create a DirectByteBuffer (using reflection) from a Chunk
+    public static ByteSource create(StoredObject so) {
+      // Since I found a way to create a DirectByteBuffer (using reflection) from a StoredObject
       // we might not even need the ByteSource abstraction any more.
       // But it is possible that createByteBuffer will not work on a different jdk so keep it for now.
-      ByteBuffer bb = chunk.createDirectByteBuffer();
+      ByteBuffer bb = so.createDirectByteBuffer();
       if (bb != null) {
         return create(bb);
       } else {
-        return new OffHeapByteSource(chunk);
+        return new OffHeapByteSource(so);
       }
     }
   }
@@ -323,10 +323,10 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
   public static class OffHeapByteSource implements ByteSource {
     private int position;
     private int limit;
-    private final ObjectStoredInMemory chunk;
+    private final StoredObject chunk;
 
-    public OffHeapByteSource(ObjectStoredInMemory c) {
-      this.chunk = c;
+    public OffHeapByteSource(StoredObject so) {
+      this.chunk = so;
       this.position = 0;
       this.limit = capacity();
     }
@@ -513,7 +513,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
       return basicGetShort(pos);
     }
     private short basicGetShort(int pos) {
-      long addr = this.chunk.getAddressForReading(pos, 2);
+      long addr = this.chunk.getAddressForReadingData(pos, 2);
       if (unaligned) {
         short result = AddressableMemoryManager.readShort(addr);
         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
@@ -537,7 +537,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
       return basicGetChar(pos);
     }
     private char basicGetChar(int pos) {
-      long addr = this.chunk.getAddressForReading(pos, 2);
+      long addr = this.chunk.getAddressForReadingData(pos, 2);
       if (unaligned) {
         char result = AddressableMemoryManager.readChar(addr);
         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
@@ -562,7 +562,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     }
     
     private int basicGetInt(final int pos) {
-      long addr = this.chunk.getAddressForReading(pos, 4);
+      long addr = this.chunk.getAddressForReadingData(pos, 4);
       if (unaligned) {
         int result = AddressableMemoryManager.readInt(addr);
         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
@@ -588,7 +588,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
       return basicGetLong(pos);
     }
     private long basicGetLong(final int pos) {
-      long addr = this.chunk.getAddressForReading(pos, 8);
+      long addr = this.chunk.getAddressForReadingData(pos, 8);
       if (unaligned) {
         long result = AddressableMemoryManager.readLong(addr);
         if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
@@ -724,7 +724,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     this.buffer = copy.buffer.duplicate();
   }
 
-  public ByteBufferInputStream(ObjectStoredInMemory blob) {
+  public ByteBufferInputStream(StoredObject blob) {
     this.buffer = ByteSourceFactory.create(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
index 635f82d..ff0871a 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
@@ -18,7 +18,7 @@ package com.gemstone.gemfire.internal.tcp;
 
 import java.nio.ByteBuffer;
 
-import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 
 /**
  * You should only create an instance of this class if the bytes this buffer reads
@@ -67,7 +67,7 @@ public class ImmutableByteBufferInputStream extends ByteBufferInputStream {
     // for serialization
   }
   
-  public ImmutableByteBufferInputStream(ObjectStoredInMemory blob) {
+  public ImmutableByteBufferInputStream(StoredObject blob) {
     super(blob);
   }
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
index 6305d3e..28252c3 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
@@ -27,7 +27,7 @@ import com.gemstone.gemfire.internal.DSCODE;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 import com.gemstone.gemfire.pdx.internal.PdxInputStream;
 
@@ -140,7 +140,7 @@ public class BlobHelper {
    * If a PdxInstance is returned then it will refer to Chunk's off-heap memory
    * with an unretained reference.
    */
-  public static @Unretained Object deserializeOffHeapBlob(ObjectStoredInMemory blob) throws IOException, ClassNotFoundException {
+  public static @Unretained Object deserializeOffHeapBlob(StoredObject blob) throws IOException, ClassNotFoundException {
     Object result;
     final long start = startDeserialization();
     // For both top level and nested pdxs we just want a reference to this off-heap blob.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java b/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
index 2cff2c4..85c6cd5 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
@@ -26,7 +26,7 @@ import java.util.Date;
 import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.InternalGemFireException;
 import com.gemstone.gemfire.pdx.PdxSerializationException;
-import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream;
 import com.gemstone.gemfire.internal.tcp.ImmutableByteBufferInputStream;
 
@@ -76,7 +76,7 @@ public class PdxInputStream extends ImmutableByteBufferInputStream {
     // for serialization
   }
 
-  public PdxInputStream(ObjectStoredInMemory blob) {
+  public PdxInputStream(StoredObject blob) {
     super(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java b/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
index 748c5e1..dce68cf 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
@@ -110,8 +110,8 @@ import com.gemstone.gemfire.internal.cache.versions.RegionVersionVector;
 import com.gemstone.gemfire.internal.cache.versions.VMRegionVersionVector;
 import com.gemstone.gemfire.internal.cache.versions.VersionTag;
 import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.gemfire.internal.offheap.AddressableStoredObject;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
@@ -2004,7 +2004,7 @@ public abstract class MultiVMRegionTestCase extends RegionTestCase {
               LocalRegion reRegion;
               reRegion = (LocalRegion) region;
               RegionEntry re = reRegion.getRegionEntry(key2);
-              AddressableStoredObject so = (AddressableStoredObject) re._getValue();
+              StoredObject so = (StoredObject) re._getValue();
               assertEquals(1, so.getRefCount());
               assertEquals(1, ma.getStats().getObjects());
             }
@@ -2091,7 +2091,7 @@ public abstract class MultiVMRegionTestCase extends RegionTestCase {
             assertEquals(2, ma.getStats().getObjects());
             LocalRegion reRegion;
             reRegion = (LocalRegion) region;
-            AddressableStoredObject so = (AddressableStoredObject) reRegion.getRegionEntry(key)._getValue();
+            StoredObject so = (StoredObject) reRegion.getRegionEntry(key)._getValue();
             assertEquals(1, so.getRefCount());
           }
         }
@@ -2157,7 +2157,7 @@ public abstract class MultiVMRegionTestCase extends RegionTestCase {
               assertEquals(2, ma.getStats().getObjects());
               LocalRegion reRegion;
               reRegion = (LocalRegion) region;
-              AddressableStoredObject so = (AddressableStoredObject) reRegion.getRegionEntry(key)._getValue();
+              StoredObject so = (StoredObject) reRegion.getRegionEntry(key)._getValue();
               assertEquals(1, so.getRefCount());
             }
           }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
index de113f6..df48ac2 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
@@ -27,21 +27,22 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.ChunkValueWrapper;
+import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.OffHeapValueWrapper;
 import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.Flushable;
 import com.gemstone.gemfire.internal.offheap.ObjectStoredInMemory;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
 import com.gemstone.gemfire.internal.offheap.SlabImpl;
+import com.gemstone.gemfire.internal.offheap.StoredObject;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
 public class ChunkValueWrapperJUnitTest {
 
-  private static ChunkValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) {
-    ObjectStoredInMemory c = (ObjectStoredInMemory)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false);
-    return new ChunkValueWrapper(c);
+  private static OffHeapValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) {
+    StoredObject c = SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false);
+    return new OffHeapValueWrapper(c);
   }
 
   @Before
@@ -81,7 +82,7 @@ public class ChunkValueWrapperJUnitTest {
   public void testSendTo() throws IOException {
     final ByteBuffer bb = ByteBuffer.allocateDirect(18);
     bb.limit(8);
-    ChunkValueWrapper vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8}, false);
+    OffHeapValueWrapper vw = createChunkValueWrapper(new byte[]{1,2,3,4,5,6,7,8}, false);
     vw.sendTo(bb, new Flushable() {
       @Override
       public void flush() throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OffHeapTestUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OffHeapTestUtil.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OffHeapTestUtil.java
index cbf3bf6..8fd6895 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OffHeapTestUtil.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/OffHeapTestUtil.java
@@ -52,7 +52,7 @@ public class OffHeapTestUtil {
     }
     
     if(orphans != null && ! orphans.isEmpty()) {
-      List<RefCountChangeInfo> info = ReferenceCountHelper.getRefCountInfo(orphans.get(0).getMemoryAddress());
+      List<RefCountChangeInfo> info = ReferenceCountHelper.getRefCountInfo(orphans.get(0).getAddress());
       System.out.println("FOUND ORPHAN!!");
       System.out.println("Sample orphan: " + orphans.get(0));
       System.out.println("Orphan info: " + info);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1a49aa43/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
index dc59474..3a3daf7 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
@@ -120,9 +120,9 @@ public class FragmentJUnitTest {
   @Test
   public void getMemoryAdressIsAlwaysFragmentBaseAddress() {
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
-    softly.assertThat(fragment.getMemoryAddress()).isEqualTo(slabs[0].getMemoryAddress());
+    softly.assertThat(fragment.getAddress()).isEqualTo(slabs[0].getMemoryAddress());
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
-    softly.assertThat(fragment.getMemoryAddress()).isEqualTo(slabs[0].getMemoryAddress());
+    softly.assertThat(fragment.getAddress()).isEqualTo(slabs[0].getMemoryAddress());
   }
   
   @Test
@@ -200,7 +200,7 @@ public class FragmentJUnitTest {
   public void fragmentHashCodeIsHashCodeOfItsMemoryAddress() {
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
-    Long fragmentAddress = fragment0.getMemoryAddress();
+    Long fragmentAddress = fragment0.getAddress();
     softly.assertThat(fragment0.hashCode()).isEqualTo(fragmentAddress.hashCode())
                                            .isNotEqualTo(fragment1.hashCode());
   }
@@ -208,7 +208,7 @@ public class FragmentJUnitTest {
   @Test
   public void fragmentFillSetsAllBytesToTheSameConstantValue() {
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
-    Long fragmentAddress = fragment.getMemoryAddress();
+    Long fragmentAddress = fragment.getAddress();
     byte[] bytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
     byte[] expectedBytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
     Arrays.fill(expectedBytes, ObjectStoredInMemory.FILL_BYTE);;