From: Mathieu Chartier Date: Thu, 18 Jun 2015 23:48:52 +0000 (-0700) Subject: Fix moving GC bug in DoFilledNewArray X-Git-Tag: android-x86-7.1-r1~889^2~958^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=52ea33b10370d60d4ce877aec529626537b7813b;p=android-x86%2Fart.git Fix moving GC bug in DoFilledNewArray Previously we read from componentClass after allocating the array. Bug: 21783443 Change-Id: I5283982edab479434e27416509e1436b4176fe01 --- diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 0f6f78801..85c1b3872 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -707,30 +707,31 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, return false; } uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - Class* arrayClass = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(), - self, false, do_access_check); - if (UNLIKELY(arrayClass == nullptr)) { + Class* array_class = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(), + self, false, do_access_check); + if (UNLIKELY(array_class == nullptr)) { DCHECK(self->IsExceptionPending()); return false; } - CHECK(arrayClass->IsArrayClass()); - Class* componentClass = arrayClass->GetComponentType(); - if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { - if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { + CHECK(array_class->IsArrayClass()); + Class* component_class = array_class->GetComponentType(); + const bool is_primitive_int_component = component_class->IsPrimitiveInt(); + if (UNLIKELY(component_class->IsPrimitive() && !is_primitive_int_component)) { + if (component_class->IsPrimitiveLong() || component_class->IsPrimitiveDouble()) { ThrowRuntimeException("Bad filled array request for type %s", - PrettyDescriptor(componentClass).c_str()); + PrettyDescriptor(component_class).c_str()); } else { self->ThrowNewExceptionF("Ljava/lang/InternalError;", "Found type %s; filled-new-array not implemented for anything but 'int'", - PrettyDescriptor(componentClass).c_str()); + PrettyDescriptor(component_class).c_str()); } return false; } - Object* newArray = Array::Alloc(self, arrayClass, length, - arrayClass->GetComponentSizeShift(), - Runtime::Current()->GetHeap()->GetCurrentAllocator()); - if (UNLIKELY(newArray == nullptr)) { - DCHECK(self->IsExceptionPending()); + Object* new_array = Array::Alloc(self, array_class, length, + array_class->GetComponentSizeShift(), + Runtime::Current()->GetHeap()->GetCurrentAllocator()); + if (UNLIKELY(new_array == nullptr)) { + self->AssertPendingOOMException(); return false; } uint32_t arg[5]; // only used in filled-new-array. @@ -740,17 +741,18 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, } else { inst->GetVarArgs(arg); } - const bool is_primitive_int_component = componentClass->IsPrimitiveInt(); for (int32_t i = 0; i < length; ++i) { size_t src_reg = is_range ? vregC + i : arg[i]; if (is_primitive_int_component) { - newArray->AsIntArray()->SetWithoutChecks(i, shadow_frame.GetVReg(src_reg)); + new_array->AsIntArray()->SetWithoutChecks( + i, shadow_frame.GetVReg(src_reg)); } else { - newArray->AsObjectArray()->SetWithoutChecks(i, shadow_frame.GetVRegReference(src_reg)); + new_array->AsObjectArray()->SetWithoutChecks( + i, shadow_frame.GetVRegReference(src_reg)); } } - result->SetL(newArray); + result->SetL(new_array); return true; }