Chromium Code Reviews| Index: runtime/vm/intermediate_language_x64.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_x64.cc (revision 23639) |
| +++ runtime/vm/intermediate_language_x64.cc (working copy) |
| @@ -23,6 +23,7 @@ |
| DECLARE_FLAG(int, optimization_counter_threshold); |
| DECLARE_FLAG(bool, propagate_ic_data); |
| +DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| // Generic summary for call instructions that have all arguments pushed |
| // on the stack and return the result in a fixed register RAX. |
| @@ -2129,6 +2130,23 @@ |
| } |
| +static void Emit53BitOverflowCheck(FlowGraphCompiler* compiler, |
| + Label* overflow, |
| + Register result) { |
| + if (FLAG_throw_on_javascript_int_overflow) { |
|
srdjan
2013/06/06 21:59:02
I think that it should be ASSERT(overflow != NULL)
Ivan Posva
2013/06/06 22:10:18
Actually if that flag is set we should just assume
|
| + if (overflow != NULL) { |
| + __ movq(TMP, result); // result is a tagged Smi. |
| + // Bits 54...64 must be all 0 or all 1. (It would be bit 53, but result |
| + // is tagged.) |
| + __ shlq(result, Immediate(64 - 54)); |
| + __ sarq(result, Immediate(64 - 54)); |
| + __ cmpq(result, TMP); |
| + __ j(NOT_EQUAL, overflow); // 53-bit overflow. |
| + } |
| + } |
| +} |
| + |
| + |
| static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| BinarySmiOpInstr* shift_left) { |
| const bool is_truncating = shift_left->is_truncating(); |
| @@ -2168,6 +2186,7 @@ |
| // Shift for result now we know there is no overflow. |
| __ shlq(left, Immediate(value)); |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| return; |
| } |
| @@ -2197,6 +2216,7 @@ |
| __ SmiUntag(right); |
| __ shlq(left, right); |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| return; |
| } |
| @@ -2247,6 +2267,7 @@ |
| // Shift for result now we know there is no overflow. |
| __ shlq(left, right); |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| } |
| @@ -2445,6 +2466,7 @@ |
| UNREACHABLE(); |
| break; |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| return; |
| } // locs()->in(1).IsConstant(). |
| @@ -2487,6 +2509,7 @@ |
| UNREACHABLE(); |
| break; |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| return; |
| } // locs()->in(1).IsStackSlot(). |
| @@ -2616,6 +2639,7 @@ |
| UNREACHABLE(); |
| break; |
| } |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| } |
| @@ -3734,6 +3758,7 @@ |
| __ shlq(temp, Immediate(1)); |
| __ j(OVERFLOW, &do_call, Assembler::kNearJump); |
| __ SmiTag(result); |
| + Emit53BitOverflowCheck(compiler, &do_call, result); |
| __ jmp(&done); |
| __ Bind(&do_call); |
| ASSERT(instance_call()->HasICData()); |
| @@ -3779,6 +3804,7 @@ |
| __ shlq(temp, Immediate(1)); |
| __ j(OVERFLOW, deopt); |
| __ SmiTag(result); |
| + Emit53BitOverflowCheck(compiler, deopt, result); |
| } |