Fix some compaction bugs in string allocation
Change-Id: I2b8499c60de7690e1012d71bccba4ecd589da9af
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index 8f5a7d4..cd5d2f6 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -54,8 +54,9 @@
// 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) {
+ SetStringCountAndBytesVisitor(int32_t count, Handle<ByteArray> src_array, int32_t offset,
+ int32_t high_byte)
+ : count_(count), src_array_(src_array), offset_(offset), high_byte_(high_byte) {
}
void operator()(Object* obj, size_t usable_size ATTRIBUTE_UNUSED) const
@@ -64,35 +65,63 @@
String* string = down_cast<String*>(obj);
string->SetCount(count_);
uint16_t* value = string->GetValue();
+ const uint8_t* const src = reinterpret_cast<uint8_t*>(src_array_->GetData()) + offset_;
for (int i = 0; i < count_; i++) {
- value[i] = high_byte_ + (src_[i] & 0xFF);
+ value[i] = high_byte_ + (src[i] & 0xFF);
}
}
private:
const int32_t count_;
- const uint8_t* const src_;
+ Handle<ByteArray> src_array_;
+ const int32_t offset_;
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 {
+class SetStringCountAndValueVisitorFromCharArray {
public:
- SetStringCountAndValueVisitor(int32_t count, uint16_t* src) : count_(count), src_(src) {
+ SetStringCountAndValueVisitorFromCharArray(int32_t count, Handle<CharArray> src_array,
+ int32_t offset) :
+ count_(count), src_array_(src_array), offset_(offset) {
}
- void operator()(Object* obj, size_t usable_size) const
+ void operator()(Object* obj, size_t usable_size ATTRIBUTE_UNUSED) 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));
+ const uint16_t* const src = src_array_->GetData() + offset_;
+ memcpy(string->GetValue(), src, count_ * sizeof(uint16_t));
}
private:
const int32_t count_;
- const uint16_t* const src_;
+ Handle<CharArray> src_array_;
+ const int32_t offset_;
+};
+
+// Sets string count and value in the allocation code path to ensure it is guarded by a CAS.
+class SetStringCountAndValueVisitorFromString {
+ public:
+ SetStringCountAndValueVisitorFromString(int32_t count, Handle<String> src_string,
+ int32_t offset) :
+ count_(count), src_string_(src_string), offset_(offset) {
+ }
+
+ 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_);
+ const uint16_t* const src = src_string_->GetValue() + offset_;
+ memcpy(string->GetValue(), src, count_ * sizeof(uint16_t));
+ }
+
+ private:
+ const int32_t count_;
+ Handle<String> src_string_;
+ const int32_t offset_;
};
inline String* String::Intern() {
@@ -140,8 +169,7 @@
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);
+ SetStringCountAndBytesVisitor visitor(byte_length, array, offset, high_byte << 8);
String* string = Alloc<kIsInstrumented>(self, byte_length, allocator_type, visitor);
return string;
}
@@ -150,8 +178,7 @@
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);
+ SetStringCountAndValueVisitorFromCharArray visitor(array_length, array, offset);
String* new_string = Alloc<kIsInstrumented>(self, array_length, allocator_type, visitor);
return new_string;
}
@@ -159,8 +186,7 @@
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);
+ SetStringCountAndValueVisitorFromString visitor(string_length, string, offset);
String* new_string = Alloc<kIsInstrumented>(self, string_length, allocator_type, visitor);
return new_string;
}