mirror of
https://github.com/dart-lang/sdk
synced 2024-10-07 10:14:53 +00:00
[vm/compiler] Fix generation of Smi immediates when using compressed pointers
When compiler generates 32-bit instructions with immediate operand (such as add/sub etc) it expects to find 32-bit immediate value. In compressed pointers mode Smi occupies 32 bits with unspecified upper bits. So getting a raw value of a Smi using static_cast<int64_t>(constant.ptr()) is not correct. For example it may yield 0xfffffffe instead of 0xfffffffffffffffe for -1 value. This change fixes a few places in code generator to use Smi::RawValue instead of doing a static_cast. TEST=runtime/tests/vm/dart/regress_47704_test.dart Fixes https://github.com/dart-lang/sdk/issues/47704 Change-Id: I1f649c5a22f221c7f4e69a884c88c265973be606 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220660 Auto-Submit: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
8dcc1dcf5e
commit
071d50f679
35
runtime/tests/vm/dart/regress_47704_test.dart
Normal file
35
runtime/tests/vm/dart/regress_47704_test.dart
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Regression test for https://github.com/dart-lang/sdk/issues/47704.
|
||||
// Verifies that compiler doesn't crash with compressed pointers when
|
||||
// generating code involving as 32-bit Smi constant which is not
|
||||
// sign-extended to 64 bits.
|
||||
|
||||
// VMOptions=--deterministic --optimization_counter_threshold=80
|
||||
|
||||
import 'dart:typed_data';
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
const int minLevel = -1;
|
||||
|
||||
void foo() {
|
||||
// Make sure this method is compiled.
|
||||
for (int i = 0; i < 100; i++) {}
|
||||
|
||||
bool ok = false;
|
||||
try {
|
||||
for (int loc0 in ((Uint16List(40)).sublist(minLevel, 42))) {
|
||||
print(loc0);
|
||||
}
|
||||
} catch (e) {
|
||||
ok = true;
|
||||
}
|
||||
Expect.isTrue(ok);
|
||||
}
|
||||
|
||||
void main() {
|
||||
foo();
|
||||
foo();
|
||||
}
|
37
runtime/tests/vm/dart_2/regress_47704_test.dart
Normal file
37
runtime/tests/vm/dart_2/regress_47704_test.dart
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Regression test for https://github.com/dart-lang/sdk/issues/47704.
|
||||
// Verifies that compiler doesn't crash with compressed pointers when
|
||||
// generating code involving as 32-bit Smi constant which is not
|
||||
// sign-extended to 64 bits.
|
||||
|
||||
// VMOptions=--deterministic --optimization_counter_threshold=80
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:typed_data';
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
const int minLevel = -1;
|
||||
|
||||
void foo() {
|
||||
// Make sure this method is compiled.
|
||||
for (int i = 0; i < 100; i++) {}
|
||||
|
||||
bool ok = false;
|
||||
try {
|
||||
for (int loc0 in ((Uint16List(40)).sublist(minLevel, 42))) {
|
||||
print(loc0);
|
||||
}
|
||||
} catch (e) {
|
||||
ok = true;
|
||||
}
|
||||
Expect.isTrue(ok);
|
||||
}
|
||||
|
||||
void main() {
|
||||
foo();
|
||||
foo();
|
||||
}
|
|
@ -1071,7 +1071,7 @@ Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
|||
Location right = locs()->in(1);
|
||||
if (right.IsConstant()) {
|
||||
ASSERT(right.constant().IsSmi());
|
||||
const int64_t imm = static_cast<int64_t>(right.constant().ptr());
|
||||
const int64_t imm = Smi::RawValue(Smi::Cast(right.constant()).Value());
|
||||
__ TestImmediate(left, imm, compiler::kObjectBytes);
|
||||
} else {
|
||||
__ tst(left, compiler::Operand(right.reg()), compiler::kObjectBytes);
|
||||
|
@ -3438,7 +3438,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
if (locs()->in(1).IsConstant()) {
|
||||
const Object& constant = locs()->in(1).constant();
|
||||
ASSERT(constant.IsSmi());
|
||||
const int64_t imm = static_cast<int64_t>(constant.ptr());
|
||||
const int64_t imm = Smi::RawValue(Smi::Cast(constant).Value());
|
||||
switch (op_kind()) {
|
||||
case Token::kADD: {
|
||||
if (deopt == NULL) {
|
||||
|
|
|
@ -1037,7 +1037,7 @@ Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
|
|||
Location right = locs()->in(1);
|
||||
if (right.IsConstant()) {
|
||||
ASSERT(right.constant().IsSmi());
|
||||
const int64_t imm = static_cast<int64_t>(right.constant().ptr());
|
||||
const int64_t imm = Smi::RawValue(Smi::Cast(right.constant()).Value());
|
||||
__ TestImmediate(left_reg, compiler::Immediate(imm),
|
||||
compiler::kObjectBytes);
|
||||
} else {
|
||||
|
@ -3487,7 +3487,8 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
|
|||
|
||||
static bool CanBeImmediate(const Object& constant) {
|
||||
return constant.IsSmi() &&
|
||||
compiler::Immediate(static_cast<int64_t>(constant.ptr())).is_int32();
|
||||
compiler::Immediate(Smi::RawValue(Smi::Cast(constant).Value()))
|
||||
.is_int32();
|
||||
}
|
||||
|
||||
static bool IsSmiValue(const Object& constant, intptr_t value) {
|
||||
|
@ -3620,7 +3621,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
if (locs()->in(1).IsConstant()) {
|
||||
const Object& constant = locs()->in(1).constant();
|
||||
ASSERT(constant.IsSmi());
|
||||
const int64_t imm = static_cast<int64_t>(constant.ptr());
|
||||
const int64_t imm = Smi::RawValue(Smi::Cast(constant).Value());
|
||||
switch (op_kind()) {
|
||||
case Token::kADD: {
|
||||
__ AddImmediate(left, compiler::Immediate(imm), compiler::kObjectBytes);
|
||||
|
|
Loading…
Reference in a new issue