DBC: Pull BadTypeError out of AssertAssignable

This was allocating a handle which is not allowed in the simulator loop.

Small improvement in Flutter's layout_bench in checked
mode. 15k us -> 14k us. 7% improvement.

R=fschneider@google.com

Review URL: https://codereview.chromium.org/2406383002 .
This commit is contained in:
Zachary Anderson 2016-10-11 11:04:17 -07:00
parent f233d759a2
commit f713658b71
3 changed files with 29 additions and 13 deletions

View file

@ -531,6 +531,11 @@ namespace dart {
// Assert that SP[-3] is assignable to variable named SP[0] of type
// SP[-1] with type arguments SP[-2] using SubtypeTestCache PP[D].
//
// - BadTypeError
//
// If SP[-3] is non-null, throws a BadType error by calling into the runtime.
// Assumes that the stack is arranged the same as for AssertAssignable.
//
// - AssertBoolean A
//
// Assert that TOS is a boolean (A = 1) or that TOS is not null (A = 0).
@ -791,6 +796,7 @@ namespace dart {
V(InstantiateType, D, lit, ___, ___) \
V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \
V(InstanceOf, A, num, ___, ___) \
V(BadTypeError, 0, ___, ___, ___) \
V(AssertAssignable, D, num, lit, ___) \
V(AssertBoolean, A, num, ___, ___) \
V(TestSmi, A_D, reg, reg, ___) \

View file

@ -230,7 +230,13 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
}
__ PushConstant(dst_type);
__ PushConstant(dst_name);
__ AssertAssignable(__ AddConstant(test_cache));
if (dst_type.IsMalformedOrMalbounded()) {
__ BadTypeError();
} else {
__ AssertAssignable(__ AddConstant(test_cache));
}
if (is_optimizing()) {
// Register allocator does not think that our first input (also used as
// output) needs to be kept alive across the call because that is how code

View file

@ -2671,22 +2671,26 @@ RawObject* Simulator::Call(const Code& code,
DISPATCH();
}
{
BYTECODE(BadTypeError, 0); // Stack: instance, type args, type, name
RawObject** args = SP - 3;
if (args[0] != null_value) {
SP[1] = args[0]; // instance.
SP[2] = args[3]; // name.
SP[3] = args[2]; // type.
Exit(thread, FP, SP + 4, pc);
NativeArguments native_args(thread, 3, SP + 1, SP - 3);
INVOKE_RUNTIME(DRT_BadTypeError, native_args);
UNREACHABLE();
}
SP -= 3;
DISPATCH();
}
{
BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
RawObject** args = SP - 3;
if (args[0] != null_value) {
const AbstractType& dst_type =
AbstractType::Handle(static_cast<RawAbstractType*>(args[2]));
if (dst_type.IsMalformedOrMalbounded()) {
SP[1] = args[0]; // instance.
SP[2] = args[3]; // name.
SP[3] = args[2]; // type.
Exit(thread, FP, SP + 4, pc);
NativeArguments native_args(thread, 3, SP + 1, SP - 3);
INVOKE_RUNTIME(DRT_BadTypeError, native_args);
UNREACHABLE();
}
RawSubtypeTestCache* cache =
static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD));
if (cache != null_value) {