Chromium Code Reviews| Index: src/arm64/lithium-codegen-arm64.cc |
| diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc |
| index 48ea7796773e0b3cb4f5638b597abd967d29f56f..8a91bb58770212ed8196189b34bed4eaa80d26d2 100644 |
| --- a/src/arm64/lithium-codegen-arm64.cc |
| +++ b/src/arm64/lithium-codegen-arm64.cc |
| @@ -2137,17 +2137,27 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { |
| UniqueSet<Map> map_set = instr->hydrogen()->map_set(); |
| Label success; |
| - for (int i = 0; i < map_set.size(); i++) { |
| - Handle<Map> map = map_set.at(i).handle(); |
| + if (map_set.size() == 1) { |
| + Handle<Map> map = map_set.at(0).handle(); |
| __ CompareMap(map_reg, map); |
| - __ B(eq, &success); |
| - } |
| - |
| - // We didn't match a map. |
| - if (instr->hydrogen()->has_migration_target()) { |
| - __ B(deferred->entry()); |
| + if (instr->hydrogen()->has_migration_target()) { |
| + __ B(ne, deferred->entry()); |
| + } else { |
| + DeoptimizeIf(ne, instr->environment()); |
| + } |
| } else { |
| - Deoptimize(instr->environment()); |
| + for (int i = 0; i < map_set.size(); i++) { |
| + Handle<Map> map = map_set.at(i).handle(); |
| + __ CompareMap(map_reg, map); |
| + __ B(eq, &success); |
| + } |
|
ulan
2014/04/04 12:04:13
Instead of checking for map_set.size() == 1, how a
Alexandre Rames
2014/04/04 13:22:54
Done.
|
| + |
| + // We didn't match a map. |
| + if (instr->hydrogen()->has_migration_target()) { |
| + __ B(deferred->entry()); |
| + } else { |
| + Deoptimize(instr->environment()); |
| + } |
| } |
| __ Bind(&success); |
| @@ -2581,19 +2591,15 @@ void LCodeGen::DoDateField(LDateField* instr) { |
| Register temp1 = x10; |
| Register temp2 = x11; |
| Smi* index = instr->index(); |
| - Label runtime, done, deopt, obj_ok; |
| + Label runtime, done; |
| ASSERT(object.is(result) && object.Is(x0)); |
| ASSERT(instr->IsMarkedAsCall()); |
| - __ JumpIfSmi(object, &deopt); |
| + DeoptimizeIfSmi(object, instr->environment()); |
| __ CompareObjectType(object, temp1, temp1, JS_DATE_TYPE); |
| - __ B(eq, &obj_ok); |
| - |
| - __ Bind(&deopt); |
| - Deoptimize(instr->environment()); |
| + DeoptimizeIf(ne, instr->environment()); |
| - __ Bind(&obj_ok); |
| if (index->value() == 0) { |
| __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset)); |
| } else { |
| @@ -2724,10 +2730,9 @@ void LCodeGen::DoDivI(LDivI* instr) { |
| return; |
| } |
| - Label deopt; |
| // Check for x / 0. |
| if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
| - __ Cbz(divisor, &deopt); |
| + DeoptimizeIfZero(divisor, instr->environment()); |
| } |
| // Check for (0 / -x) as that will produce negative zero. |
| @@ -2739,7 +2744,7 @@ void LCodeGen::DoDivI(LDivI* instr) { |
| // If the divisor >= 0 (pl, the opposite of mi) set the flags to |
| // condition ne, so we don't deopt, ie. positive divisor doesn't deopt. |
| __ Ccmp(dividend, 0, NoFlag, mi); |
| - __ B(eq, &deopt); |
| + DeoptimizeIf(eq, instr->environment()); |
| } |
| // Check for (kMinInt / -1). |
| @@ -2751,19 +2756,13 @@ void LCodeGen::DoDivI(LDivI* instr) { |
| // -1. If overflow is clear, set the flags for condition ne, as the |
| // dividend isn't -1, and thus we shouldn't deopt. |
| __ Ccmp(divisor, -1, NoFlag, vs); |
| - __ B(eq, &deopt); |
| + DeoptimizeIf(eq, instr->environment()); |
| } |
| // Compute remainder and deopt if it's not zero. |
| Register remainder = ToRegister32(instr->temp()); |
| __ Msub(remainder, result, divisor, dividend); |
| - __ Cbnz(remainder, &deopt); |
| - |
| - Label div_ok; |
| - __ B(&div_ok); |
| - __ Bind(&deopt); |
| - Deoptimize(instr->environment()); |
| - __ Bind(&div_ok); |
| + DeoptimizeIfNotZero(remainder, instr->environment()); |
| } |
| @@ -2850,19 +2849,18 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
| ASSERT(instr->IsMarkedAsCall()); |
| ASSERT(object.Is(x0)); |
| - Label deopt; |
| - |
| - __ JumpIfRoot(object, Heap::kUndefinedValueRootIndex, &deopt); |
| + DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, |
| + instr->environment()); |
| __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
| __ Cmp(object, null_value); |
| - __ B(eq, &deopt); |
| + DeoptimizeIf(eq, instr->environment()); |
| - __ JumpIfSmi(object, &deopt); |
| + DeoptimizeIfSmi(object, instr->environment()); |
| STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| __ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE); |
| - __ B(le, &deopt); |
| + DeoptimizeIf(le, instr->environment()); |
| Label use_cache, call_runtime; |
| __ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime); |
| @@ -2870,16 +2868,13 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
| __ Ldr(object, FieldMemOperand(object, HeapObject::kMapOffset)); |
| __ B(&use_cache); |
| - __ Bind(&deopt); |
| - Deoptimize(instr->environment()); |
| - |
| // Get the set of properties to enumerate. |
| __ Bind(&call_runtime); |
| __ Push(object); |
| CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); |
| __ Ldr(x1, FieldMemOperand(object, HeapObject::kMapOffset)); |
| - __ JumpIfNotRoot(x1, Heap::kMetaMapRootIndex, &deopt); |
| + DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr->environment()); |
| __ Bind(&use_cache); |
| } |
| @@ -3287,11 +3282,11 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| Register function = ToRegister(instr->function()); |
| Register result = ToRegister(instr->result()); |
| Register temp = ToRegister(instr->temp()); |
| - Label deopt; |
| // Check that the function really is a function. Leaves map in the result |
| // register. |
| - __ JumpIfNotObjectType(function, result, temp, JS_FUNCTION_TYPE, &deopt); |
| + __ CompareObjectType(function, result, temp, JS_FUNCTION_TYPE); |
| + DeoptimizeIf(ne, instr->environment()); |
| // Make sure that the function has an instance prototype. |
| Label non_instance; |
| @@ -3303,7 +3298,8 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| JSFunction::kPrototypeOrInitialMapOffset)); |
| // Check that the function has a prototype or an initial map. |
| - __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &deopt); |
| + DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, |
| + instr->environment()); |
| // If the function does not have an initial map, we're done. |
| Label done; |
| @@ -3318,11 +3314,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| // map. |
| __ Bind(&non_instance); |
| __ Ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); |
| - __ B(&done); |
| - |
| - // Deoptimize case. |
| - __ Bind(&deopt); |
| - Deoptimize(instr->environment()); |
| // All done. |
| __ Bind(&done); |
| @@ -3690,10 +3681,8 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| : ToRegister32(instr->value()); |
| Register result = r.IsSmi() ? ToRegister(instr->result()) |
| : ToRegister32(instr->result()); |
| - Label done; |
| - __ Abs(result, input, NULL, &done); |
| - Deoptimize(instr->environment()); |
| - __ Bind(&done); |
| + __ Abs(result, input); |
| + DeoptimizeIf(vs, instr->environment()); |
| } |
| } |
| @@ -4224,25 +4213,16 @@ void LCodeGen::DoModI(LModI* instr) { |
| Register divisor = ToRegister32(instr->right()); |
| Register result = ToRegister32(instr->result()); |
| - Label deopt, done; |
| + Label done; |
| // modulo = dividend - quotient * divisor |
| __ Sdiv(result, dividend, divisor); |
| if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| - // Combine the deoptimization sites. |
| - Label ok; |
| - __ Cbnz(divisor, &ok); |
| - __ Bind(&deopt); |
| - Deoptimize(instr->environment()); |
| - __ Bind(&ok); |
| + DeoptimizeIfZero(divisor, instr->environment()); |
| } |
| __ Msub(result, result, divisor, dividend); |
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| __ Cbnz(result, &done); |
| - if (deopt.is_bound()) { // TODO(all) This is a hack, remove this... |
| - __ Tbnz(dividend, kWSignBit, &deopt); |
| - } else { |
| - DeoptimizeIfNegative(dividend, instr->environment()); |
| - } |
| + DeoptimizeIfNegative(dividend, instr->environment()); |
| } |
| __ Bind(&done); |
| } |
| @@ -5708,8 +5688,8 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| Register temp2 = ToRegister(instr->temp2()); |
| Label no_memento_found; |
| - __ JumpIfJSArrayHasAllocationMemento(object, temp1, temp2, &no_memento_found); |
| - Deoptimize(instr->environment()); |
| + __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found); |
| + DeoptimizeIf(eq, instr->environment()); |
| __ Bind(&no_memento_found); |
| } |
| @@ -5842,7 +5822,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { |
| // If the receiver is null or undefined, we have to pass the global object as |
| // a receiver to normal functions. Values have to be passed unchanged to |
| // builtins and strict-mode functions. |
| - Label global_object, done, deopt; |
| + Label global_object, done; |
| if (!instr->hydrogen()->known_function()) { |
| __ Ldr(result, FieldMemOperand(function, |
| @@ -5864,13 +5844,10 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { |
| __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object); |
| // Deoptimize if the receiver is not a JS object. |
| - __ JumpIfSmi(receiver, &deopt); |
| + DeoptimizeIfSmi(receiver, instr->environment()); |
| __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE); |
| __ Mov(result, receiver); |
| __ B(ge, &done); |
| - // Otherwise, fall through to deopt. |
| - |
| - __ Bind(&deopt); |
| Deoptimize(instr->environment()); |
| __ Bind(&global_object); |