diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index b367cff..8f5a7d4 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -19,6 +19,7 @@
 
 #include "array.h"
 #include "class.h"
+#include "gc/heap-inl.h"
 #include "intern_table.h"
 #include "runtime.h"
 #include "string.h"
@@ -29,41 +30,147 @@
 namespace mirror {
 
 inline uint32_t String::ClassSize() {
-  uint32_t vtable_entries = Object::kVTableLength + 51;
+  uint32_t vtable_entries = Object::kVTableLength + 52;
   return Class::ComputeClassSize(true, vtable_entries, 0, 1, 0, 1, 2);
 }
 
-inline uint16_t String::UncheckedCharAt(int32_t index) {
-  return GetCharArray()->Get(index + GetOffset());
-}
+// Sets string count in the allocation code path to ensure it is guarded by a CAS.
+class SetStringCountVisitor {
+ public:
+  explicit SetStringCountVisitor(int32_t count) : count_(count) {
+  }
 
-inline CharArray* String::GetCharArray() {
-  return GetFieldObject<CharArray>(ValueOffset());
-}
+  void operator()(Object* obj, size_t usable_size ATTRIBUTE_UNUSED) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    // Avoid AsString as object is not yet in live bitmap or allocation stack.
+    String* string = down_cast<String*>(obj);
+    string->SetCount(count_);
+  }
 
-inline int32_t String::GetLength() {
-  int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_));
-  DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
-  return result;
-}
+ private:
+  const int32_t count_;
+};
 
-inline void String::SetArray(CharArray* new_array) {
-  // Array is invariant so use non-transactional mode. Also disable check as we may run inside
-  // a transaction.
-  DCHECK(new_array != nullptr);
-  SetFieldObject<false, false>(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array);
-}
+// Sets string count and value in the allocation code path to ensure it is guarded by a CAS.
+class SetStringCountAndBytesVisitor {
+ public:
+  SetStringCountAndBytesVisitor(int32_t count, uint8_t* src, int32_t high_byte)
+      : count_(count), src_(src), high_byte_(high_byte) {
+  }
+
+  void operator()(Object* obj, size_t usable_size ATTRIBUTE_UNUSED) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    // Avoid AsString as object is not yet in live bitmap or allocation stack.
+    String* string = down_cast<String*>(obj);
+    string->SetCount(count_);
+    uint16_t* value = string->GetValue();
+    for (int i = 0; i < count_; i++) {
+      value[i] = high_byte_ + (src_[i] & 0xFF);
+    }
+  }
+
+ private:
+  const int32_t count_;
+  const uint8_t* const src_;
+  const int32_t high_byte_;
+};
+
+// Sets string count and value in the allocation code path to ensure it is guarded by a CAS.
+class SetStringCountAndValueVisitor {
+ public:
+  SetStringCountAndValueVisitor(int32_t count, uint16_t* src) : count_(count), src_(src) {
+  }
+
+  void operator()(Object* obj, size_t usable_size) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    UNUSED(usable_size);
+    // Avoid AsString as object is not yet in live bitmap or allocation stack.
+    String* string = down_cast<String*>(obj);
+    string->SetCount(count_);
+    memcpy(string->GetValue(), src_, count_ * sizeof(uint16_t));
+  }
+
+ private:
+  const int32_t count_;
+  const uint16_t* const src_;
+};
 
 inline String* String::Intern() {
   return Runtime::Current()->GetInternTable()->InternWeak(this);
 }
 
+inline uint16_t String::CharAt(int32_t index) {
+  int32_t count = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_));
+  if (UNLIKELY((index < 0) || (index >= count))) {
+    Thread* self = Thread::Current();
+    self->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
+                             "length=%i; index=%i", count, index);
+    return 0;
+  }
+  return GetValue()[index];
+}
+
+template<VerifyObjectFlags kVerifyFlags>
+inline size_t String::SizeOf() {
+  return sizeof(String) + (sizeof(uint16_t) * GetLength<kVerifyFlags>());
+}
+
+template <bool kIsInstrumented, typename PreFenceVisitor>
+inline String* String::Alloc(Thread* self, int32_t utf16_length, gc::AllocatorType allocator_type,
+                             const PreFenceVisitor& pre_fence_visitor) {
+  size_t header_size = sizeof(String);
+  size_t data_size = sizeof(uint16_t) * utf16_length;
+  size_t size = header_size + data_size;
+  Class* string_class = GetJavaLangString();
+
+  // Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
+  if (UNLIKELY(size < data_size)) {
+    self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
+                                             PrettyDescriptor(string_class).c_str(),
+                                             utf16_length).c_str());
+    return nullptr;
+  }
+  gc::Heap* heap = Runtime::Current()->GetHeap();
+  return down_cast<String*>(
+      heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, string_class, size,
+                                                             allocator_type, pre_fence_visitor));
+}
+
+template <bool kIsInstrumented>
+inline String* String::AllocFromByteArray(Thread* self, int32_t byte_length,
+                                          Handle<ByteArray> array, int32_t offset,
+                                          int32_t high_byte, gc::AllocatorType allocator_type) {
+  uint8_t* data = reinterpret_cast<uint8_t*>(array->GetData()) + offset;
+  SetStringCountAndBytesVisitor visitor(byte_length, data, high_byte << 8);
+  String* string = Alloc<kIsInstrumented>(self, byte_length, allocator_type, visitor);
+  return string;
+}
+
+template <bool kIsInstrumented>
+inline String* String::AllocFromCharArray(Thread* self, int32_t array_length,
+                                          Handle<CharArray> array, int32_t offset,
+                                          gc::AllocatorType allocator_type) {
+  uint16_t* data = array->GetData() + offset;
+  SetStringCountAndValueVisitor visitor(array_length, data);
+  String* new_string = Alloc<kIsInstrumented>(self, array_length, allocator_type, visitor);
+  return new_string;
+}
+
+template <bool kIsInstrumented>
+inline String* String::AllocFromString(Thread* self, int32_t string_length, Handle<String> string,
+                                       int32_t offset, gc::AllocatorType allocator_type) {
+  uint16_t* data = string->GetValue() + offset;
+  SetStringCountAndValueVisitor visitor(string_length, data);
+  String* new_string = Alloc<kIsInstrumented>(self, string_length, allocator_type, visitor);
+  return new_string;
+}
+
 inline int32_t String::GetHashCode() {
   int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_));
   if (UNLIKELY(result == 0)) {
     result = ComputeHashCode();
   }
-  DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
+  DCHECK(result != 0 || ComputeUtf16Hash(GetValue(), GetLength()) == 0)
       << ToModifiedUtf8() << " " << result;
   return result;
 }
