Version 2.14.0-58.0.dev
Merge commit 'd9f9b4dc96064879a8187b48ed62a7cbc32abc2c' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index ea72f96..c4fe216 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1444,7 +1444,7 @@
@override
Constant visitConstructorInvocation(ConstructorInvocation node) {
- if (!node.isConst) {
+ if (!node.isConst && !enableConstFunctions) {
return createInvalidExpressionConstant(
node, 'Non-constant constructor invocation "$node".');
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart
index 775b623..ff214a1 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart
@@ -23,6 +23,9 @@
}
}
+const var3 = fn();
+A fn() => A();
+
void main() {
Expect.equals(var1.name, printString);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.expect
index 3ad815a..d85a9e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.expect
@@ -21,6 +21,9 @@
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
+static const field self::A var3 = #C3;
+static method fn() → self::A
+ return new self::A::•();
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.transformed.expect
index 3ad815a..d85a9e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.strong.transformed.expect
@@ -21,6 +21,9 @@
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
+static const field self::A var3 = #C3;
+static method fn() → self::A
+ return new self::A::•();
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.textual_outline.expect
index bbb2129..ed41a789 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.textual_outline.expect
@@ -9,4 +9,6 @@
class A {
const A() {}
}
+const var3 = fn();
+A fn() => A();
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.expect
index 3ad815a..d85a9e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.expect
@@ -21,6 +21,9 @@
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
+static const field self::A var3 = #C3;
+static method fn() → self::A
+ return new self::A::•();
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.outline.expect
index 7c13957..eecc3aa 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.outline.expect
@@ -18,6 +18,9 @@
static const field core::String printString = "print";
static const field self::Simple var1 = const self::Simple::•(self::printString);
static const field self::A var2 = const self::A::•();
+static const field self::A var3 = self::fn();
+static method fn() → self::A
+ ;
static method main() → void
;
@@ -25,4 +28,4 @@
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor.dart:10:14 -> InstanceConstant(const Simple{Simple.name: "print"})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor.dart:19:14 -> InstanceConstant(const A{})
-Extra constant evaluation: evaluated: 3, effectively constant: 2
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.transformed.expect
index 3ad815a..d85a9e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor.dart.weak.transformed.expect
@@ -21,6 +21,9 @@
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
+static const field self::A var3 = #C3;
+static method fn() → self::A
+ return new self::A::•();
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart
index 642c066..e5df17a 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart
@@ -38,4 +38,9 @@
const B() : super();
}
+const var4 = C();
+class C {
+ int? x;
+}
+
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.expect
index fde5c0dd..8f500e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.expect
@@ -2,6 +2,11 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const var4 = C();
+// ^
+//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
@@ -60,6 +65,12 @@
: super self::A::•()
;
}
+class C extends core::Object {
+ field core::int? x = null;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
@@ -67,6 +78,10 @@
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
+static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+const var4 = C();
+ ^";
static method main() → void {}
constants {
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.transformed.expect
index aac0f05..1aea02c 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.transformed.expect
@@ -2,6 +2,11 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const var4 = C();
+// ^
+//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
@@ -60,6 +65,12 @@
: super self::A::•()
;
}
+class C extends core::Object {
+ field core::int? x = null;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
@@ -67,6 +78,10 @@
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
+static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+const var4 = C();
+ ^";
static method main() → void {}
constants {
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.textual_outline.expect
index 86a66c8..31bb618 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.textual_outline.expect
@@ -17,4 +17,8 @@
class B extends A {
const B() : super();
}
+const var4 = C();
+class C {
+ int? x;
+}
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.expect
index fde5c0dd..8f500e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.expect
@@ -2,6 +2,11 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const var4 = C();
+// ^
+//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
@@ -60,6 +65,12 @@
: super self::A::•()
;
}
+class C extends core::Object {
+ field core::int? x = null;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
@@ -67,6 +78,10 @@
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
+static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+const var4 = C();
+ ^";
static method main() → void {}
constants {
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.outline.expect
index 2c363dd..f6cf6a09a 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.outline.expect
@@ -1,4 +1,12 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const var4 = C();
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -26,10 +34,19 @@
: super self::A::•()
;
}
+class C extends core::Object {
+ field core::int? x;
+ synthetic constructor •() → self::C
+ ;
+}
static const field core::String printString = "print";
static const field self::Simple var1 = const self::Simple::•(self::printString);
static const field self::Simple2 var2 = const self::Simple2::•(self::printString);
static const field self::B var3 = const self::B::•();
+static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+const var4 = C();
+ ^";
static method main() → void
;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.transformed.expect
index aac0f05..1aea02c 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.transformed.expect
@@ -2,6 +2,11 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const var4 = C();
+// ^
+//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
@@ -60,6 +65,12 @@
: super self::A::•()
;
}
+class C extends core::Object {
+ field core::int? x = null;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
@@ -67,6 +78,10 @@
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
+static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+const var4 = C();
+ ^";
static method main() → void {}
constants {
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 8dcac15..0990227 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -82,20 +82,27 @@
void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
+ void* hint = nullptr;
int prot = PROT_NONE;
+ int flags = MAP_PRIVATE;
switch (type) {
case kReadOnly:
prot = PROT_READ;
break;
case kReadExecute:
+ // Try to allocate near the VM's binary.
+ hint = reinterpret_cast<void*>(&Dart_Initialize);
prot = PROT_READ | PROT_EXEC;
break;
case kReadWrite:
prot = PROT_READ | PROT_WRITE;
break;
}
- const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
- void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
+ if (start != nullptr) {
+ hint = start;
+ flags |= MAP_FIXED;
+ }
+ void* addr = mmap(hint, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index e2e87d8..b466119 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -84,20 +84,27 @@
void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
+ void* hint = nullptr;
int prot = PROT_NONE;
+ int flags = MAP_PRIVATE;
switch (type) {
case kReadOnly:
prot = PROT_READ;
break;
case kReadExecute:
+ // Try to allocate near the VM's binary.
+ hint = reinterpret_cast<void*>(&Dart_Initialize);
prot = PROT_READ | PROT_EXEC;
break;
case kReadWrite:
prot = PROT_READ | PROT_WRITE;
break;
}
- const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
- void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
+ if (start != nullptr) {
+ hint = start;
+ flags |= MAP_FIXED;
+ }
+ void* addr = mmap(hint, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 2f6ca67..79c084c 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -81,20 +81,27 @@
void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
+ void* hint = nullptr;
int prot = PROT_NONE;
+ int flags = MAP_PRIVATE;
switch (type) {
case kReadOnly:
prot = PROT_READ;
break;
case kReadExecute:
+ // Try to allocate near the VM's binary.
+ hint = reinterpret_cast<void*>(&Dart_Initialize);
prot = PROT_READ | PROT_EXEC;
break;
case kReadWrite:
prot = PROT_READ | PROT_WRITE;
break;
}
- const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
- void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
+ if (start != nullptr) {
+ hint = start;
+ flags |= MAP_FIXED;
+ }
+ void* addr = mmap(hint, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index b036ac8..fc546c3 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -82,6 +82,7 @@
void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
+ void* hint = nullptr;
int prot = PROT_NONE;
int map_flags = MAP_PRIVATE;
switch (type) {
@@ -89,6 +90,8 @@
prot = PROT_READ;
break;
case kReadExecute:
+ // Try to allocate near the VM's binary.
+ hint = reinterpret_cast<void*>(&Dart_Initialize);
prot = PROT_READ | PROT_EXEC;
if (IsAtLeastOS10_14()) {
map_flags |= (MAP_JIT | MAP_ANONYMOUS);
@@ -99,6 +102,7 @@
break;
}
if (start != nullptr) {
+ hint = start;
map_flags |= MAP_FIXED;
}
void* addr = start;
@@ -107,7 +111,7 @@
// directly. We must first copy it into an anonymous mapping and then mark
// the mapping as executable.
if (addr == nullptr) {
- addr = mmap(nullptr, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
+ addr = mmap(hint, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
if (addr == MAP_FAILED) {
Syslog::PrintErr("mmap failed %s\n", strerror(errno));
return nullptr;
@@ -139,7 +143,7 @@
return nullptr;
}
} else {
- addr = mmap(addr, length, prot, map_flags, handle_->fd(), position);
+ addr = mmap(hint, length, prot, map_flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
Syslog::PrintErr("mmap failed %s\n", strerror(errno));
return nullptr;
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 1e0b8f8..aeb4a52 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -46,13 +46,14 @@
static void unmap(uword start, uword end);
-static void* GenericMapAligned(int prot,
+static void* GenericMapAligned(void* hint,
+ int prot,
intptr_t size,
intptr_t alignment,
intptr_t allocated_size,
int map_flags) {
- void* address = mmap(nullptr, allocated_size, prot, map_flags, -1, 0);
- LOG_INFO("mmap(nullptr, 0x%" Px ", %u, ...): %p\n", allocated_size, prot,
+ void* address = mmap(hint, allocated_size, prot, map_flags, -1, 0);
+ LOG_INFO("mmap(%p, 0x%" Px ", %u, ...): %p\n", hint, allocated_size, prot,
address);
if (address == MAP_FAILED) {
return nullptr;
@@ -77,7 +78,7 @@
#if defined(DART_COMPRESSED_POINTERS)
if (VirtualMemoryCompressedHeap::GetRegion() == nullptr) {
void* address = GenericMapAligned(
- PROT_NONE, kCompressedHeapSize, kCompressedHeapAlignment,
+ nullptr, PROT_NONE, kCompressedHeapSize, kCompressedHeapAlignment,
kCompressedHeapSize + kCompressedHeapAlignment,
MAP_PRIVATE | MAP_ANONYMOUS);
if (address == nullptr) {
@@ -200,14 +201,15 @@
#endif
}
-static void* MapAligned(int fd,
+static void* MapAligned(void* hint,
+ int fd,
int prot,
intptr_t size,
intptr_t alignment,
intptr_t allocated_size) {
- void* address = mmap(nullptr, allocated_size, PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- LOG_INFO("mmap(nullptr, 0x%" Px ", PROT_NONE, ...): %p\n", allocated_size,
+ void* address =
+ mmap(hint, allocated_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ LOG_INFO("mmap(%p, 0x%" Px ", PROT_NONE, ...): %p\n", hint, allocated_size,
address);
if (address == MAP_FAILED) {
return nullptr;
@@ -276,7 +278,7 @@
}
const int region_prot = PROT_READ | PROT_WRITE;
void* region_ptr =
- MapAligned(fd, region_prot, size, alignment, allocated_size);
+ MapAligned(nullptr, fd, region_prot, size, alignment, allocated_size);
if (region_ptr == nullptr) {
close(fd);
return nullptr;
@@ -287,8 +289,9 @@
// DUAL_MAPPING_SUPPORTED is false in TARGET_OS_MACOS and hence support
// for MAP_JIT is not required here.
const int alias_prot = PROT_READ | PROT_EXEC;
+ void* hint = reinterpret_cast<void*>(&Dart_Initialize);
void* alias_ptr =
- MapAligned(fd, alias_prot, size, alignment, allocated_size);
+ MapAligned(hint, fd, alias_prot, size, alignment, allocated_size);
close(fd);
if (alias_ptr == nullptr) {
const uword region_base = reinterpret_cast<uword>(region_ptr);
@@ -318,7 +321,8 @@
close(fd);
return nullptr;
}
- void* region_ptr = MapAligned(fd, prot, size, alignment, allocated_size);
+ void* region_ptr =
+ MapAligned(nullptr, fd, prot, size, alignment, allocated_size);
close(fd);
if (region_ptr == nullptr) {
return nullptr;
@@ -334,8 +338,18 @@
map_flags |= MAP_JIT;
}
#endif // defined(HOST_OS_MACOS)
+
+ void* hint = nullptr;
+ // Some 64-bit microarchitectures store only the low 32-bits of targets as
+ // part of indirect branch prediction, predicting that the target's upper bits
+ // will be same as the call instruction's address. This leads to misprediction
+ // for indirect calls crossing a 4GB boundary. We ask mmap to place our
+ // generated code near the VM binary to avoid this.
+ if (is_executable) {
+ hint = reinterpret_cast<void*>(&Dart_Initialize);
+ }
void* address =
- GenericMapAligned(prot, size, alignment, allocated_size, map_flags);
+ GenericMapAligned(hint, prot, size, alignment, allocated_size, map_flags);
if (address == nullptr) {
return nullptr;
}
diff --git a/tests/language/const_functions/const_functions_const_ctor_error_test.dart b/tests/language/const_functions/const_functions_const_ctor_error_test.dart
index 69fbe69..e8aec9e 100644
--- a/tests/language/const_functions/const_functions_const_ctor_error_test.dart
+++ b/tests/language/const_functions/const_functions_const_ctor_error_test.dart
@@ -53,3 +53,13 @@
class B extends A {
const B() : super();
}
+
+const var4 = C();
+// ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
+// ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
+class C {
+ int? x;
+}
diff --git a/tests/language/const_functions/const_functions_const_ctor_test.dart b/tests/language/const_functions/const_functions_const_ctor_test.dart
index 0430cce..ad4a7ce 100644
--- a/tests/language/const_functions/const_functions_const_ctor_test.dart
+++ b/tests/language/const_functions/const_functions_const_ctor_test.dart
@@ -29,6 +29,11 @@
}
}
+const var3 = fn();
+// ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+A fn() => A();
+
void main() {
Expect.equals(var1.name, printString);
}
diff --git a/tools/VERSION b/tools/VERSION
index a7042d9..1372d22 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 57
+PRERELEASE 58
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/create_timestamp_file.py b/tools/create_timestamp_file.py
deleted file mode 100755
index bb48e7f..0000000
--- a/tools/create_timestamp_file.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2013, 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.
-
-import sys
-import os
-
-
-def main(args):
- for file_name in args[1:]:
- dir_name = os.path.dirname(file_name)
- if not os.path.exists(dir_name):
- os.mkdir(dir_name)
- open(file_name, 'w').close()
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/tools/list_dart_files_as_depfile.py b/tools/list_dart_files_as_depfile.py
new file mode 100644
index 0000000..f03e7ad
--- /dev/null
+++ b/tools/list_dart_files_as_depfile.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+# Copyright (c) 2016, 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.
+"""Tool for listing Dart source files.
+
+If the first argument is 'relative', the script produces paths relative to the
+current working directory. If the first argument is 'absolute', the script
+produces absolute paths.
+
+Usage:
+ python3 tools/list_dart_files_as_depfile.py <depfile> <directory> <pattern>
+"""
+
+import os
+import re
+import sys
+
+
+def main(argv):
+ depfile = argv[1]
+ directory = argv[2]
+ if not os.path.isabs(directory):
+ directory = os.path.realpath(directory)
+
+ pattern = None
+ if len(argv) > 3:
+ pattern = re.compile(argv[3])
+
+ # Output a GN depfile, whose format is a Makefile with one target.
+ out = open(depfile, 'w')
+ out.write(depfile)
+ out.write(":")
+
+ for root, directories, files in os.walk(directory):
+ # We only care about actual source files, not generated code or tests.
+ for skip_dir in ['.git', 'gen', 'test']:
+ if skip_dir in directories:
+ directories.remove(skip_dir)
+
+ # If we are looking at the root directory, filter the immediate
+ # subdirectories by the given pattern.
+ if pattern and root == directory:
+ directories[:] = filter(pattern.match, directories)
+
+ for filename in files:
+ if filename.endswith(
+ '.dart') and not filename.endswith('_test.dart'):
+ fullname = os.path.join(directory, root, filename)
+ fullname = fullname.replace(os.sep, '/')
+ out.write(" \"")
+ out.write(fullname)
+ out.write("\"")
+
+ out.write("\n")
+ out.close()
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/utils/create_timestamp.gni b/utils/create_timestamp.gni
index 835700a..3b39299 100644
--- a/utils/create_timestamp.gni
+++ b/utils/create_timestamp.gni
@@ -10,16 +10,15 @@
path = invoker.path
output = invoker.output
action(target_name) {
- list_args = [ path ]
+ script = "$_dart_root/tools/list_dart_files_as_depfile.py"
+ args = [
+ rebase_path(output),
+ path,
+ ]
if (defined(invoker.pattern)) {
- list_args += [ invoker.pattern ]
+ args += [ invoker.pattern ]
}
- files = exec_script("$_dart_root/tools/list_dart_files.py",
- [ "absolute" ] + list_args,
- "list lines")
- inputs = [ "$_dart_root/tools/list_dart_files.py" ] + files
+ depfile = output
outputs = [ output ]
- script = "$_dart_root/tools/create_timestamp_file.py"
- args = [ rebase_path(output) ]
}
}