Revert "[VM] Add @pragma annotations on Field, make @pragma annotations work generally"
This reverts commit 2de63ac01c3f092b24da50d1080617f3244e7b05.
Reason for revert: This triggers shutdown deadlocks for some reason:
#0 0xf7782cd9 __kernel_vsyscall
#1 0xf7753d0b pthread_cond_wait@@GLIBC_2.3.2
#2 0x0108a515 dart::Monitor::WaitMicros(long long)
#3 0x0108a467 dart::Monitor::Wait(long long)
#4 0x00fe9048 dart::KernelIsolate::Shutdown()
#5 0x00f99ae4 dart::Dart::Cleanup()
#6 0x01278fce Dart_Cleanup
#7 0x00dd347e dart::bin::main(int, char**)
#8 0x00dd3d64 main
#9 0xf745caf3 __libc_start_main
#10 0x00dd2021 _start
TID 30443:
#0 0xf7782cd9 __kernel_vsyscall
#1 0xf7531ee6 epoll_wait
#2 0x00ddab61 dart::bin::EventHandlerImplementation::Poll(unsigned int)
#3 0x00dfb2d4 dart::bin::ThreadStart(void*)
#4 0xf774ff72 start_thread
#5 0xf753143e __clone
TID 30444:
#0 0xf7782cd9 __kernel_vsyscall
#1 0xf7753d0b pthread_cond_wait@@GLIBC_2.3.2
#2 0x0108a515 dart::Monitor::WaitMicros(long long)
#3 0x0108a467 dart::Monitor::Wait(long long)
#4 0x012484d8 dart::BackgroundCompiler::Run()
#5 0x01248a37 dart::BackgroundCompilerTask::Run()
#6 0x0112203a dart::ThreadPool::Worker::Loop()
#7 0x01121efe dart::ThreadPool::Worker::Main(unsigned int)
#8 0x01089e73 dart::ThreadStart(void*)
#9 0xf774ff72 start_thread
#10 0xf753143e __clone
Original change's description:
> [VM] Add @pragma annotations on Field, make @pragma annotations work generally
>
> Currently the @pramga('vm:exact-result-type') annotation only works if
> the function is a recognized method. This change changes that to make
> the VM just look if a function has the annotation (no matter if it's
> also in the list of recognized methods or not).
>
> Furthermore this CL adds a "has_pragma" bit to [Field] objects, similar
> to how we have it on [Function]/[Class]es. This allows annotating
> fields with types, as we do with function return types.
>
> Furthermore this CL lets the type propgagator use
> @pragma('vm:exact-result-type') annotations to narrow the [CompileType]
> set on [LoadFieldInstr]s.
>
> Since the @pragma is a general feature, this CL moves the
> `Function::FindPragma()` to `Library::FindPragma` (which is where any
> other metadata lookup happens). We also let the `FindPragma` accept any
> of Class/Function/Field objects.
>
> Furthermore this CL adds a bailout if we try to evaluate metadata in
> the background compiler, since the background compiler is not allowed
> to execute generated code. The bailout should trigger a re-compilation
> on the mutator thread.
>
> Furthermore the `FindPragma()` function is fixed to handle the case
> when the evaluation of the metadata results in e.g. a language error.
> In this case we simply claim to not have found a pragma annotation.
>
> Issue https://github.com/dart-lang/sdk/issues/31954
>
> Change-Id: I0900a80d5ae0f3e8d09baf13cba1b20dd974df31
> Reviewed-on: https://dart-review.googlesource.com/c/84037
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
TBR=vegorov@google.com,kustermann@google.com,alexmarkov@google.com,sjindel@google.com
Change-Id: Ic0d22d32b0eea3a76ec245cabab0006f97ca1b05
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/84622
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index 99b4e7c..dd7d88a 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -5,7 +5,6 @@
// part of "common_patch.dart";
@patch
-@pragma("vm:entry-point")
class _Platform {
@patch
static int _numberOfProcessors() native "Platform_NumberOfProcessors";
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 373eb7d..375fb93 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -192,7 +192,6 @@
static _currentRss() native "ProcessInfo_CurrentRSS";
}
-@pragma("vm:entry-point")
class _ProcessStartStatus {
@pragma("vm:entry-point", "set")
int _errorCode; // Set to OS error code if process start failed.
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index 876e789..5d61f88 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -64,7 +64,6 @@
* are backed by an external C array of bytes, so that both Dart code and
* native code can access the same data.
*/
-@pragma("vm:entry-point")
class _SecureFilterImpl extends NativeFieldWrapperClass1
implements _SecureFilter {
// Performance is improved if a full buffer of plaintext fits
diff --git a/runtime/docs/compiler/result_type_pragma.md b/runtime/docs/compiler/result_type_pragma.md
index 8c72b13..2bc5032 100644
--- a/runtime/docs/compiler/result_type_pragma.md
+++ b/runtime/docs/compiler/result_type_pragma.md
@@ -5,9 +5,6 @@
the return type in the signature of the method. There are three limitations on
this pragma:
-Similarly if a field is marked with the same annotation it must be guaranteed
-that a load from the field returns in the specified exact result type.
-
0. The Dart object returned by the method at runtime must have exactly the type
specified in the annotation (not a subtype).
@@ -35,11 +32,6 @@
@pragma('vm:exact-result-type', B)
A foo() native 'foo_impl';
-
-class C {
- @pragma('vm:exact-result-type', int)
- final int value;
-}
```
### Reference to type via path
@@ -47,10 +39,4 @@
```dart
@pragma('vm:exact-result-type', 'dart:core#_Smi');
int foo() native 'foo_impl';
-
-class C {
- @pragma('vm:exact-result-type', 'dart:core#_Smi')
- final int value;
-}
-
```
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index daa7248..f9f3441 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1001,7 +1001,7 @@
s->Write<int32_t>(field->ptr()->kernel_offset_);
#endif
}
- s->Write<uint16_t>(field->ptr()->kind_bits_);
+ s->Write<uint8_t>(field->ptr()->kind_bits_);
}
}
@@ -1053,7 +1053,7 @@
field->ptr()->kernel_offset_ = d->Read<int32_t>();
#endif
}
- field->ptr()->kind_bits_ = d->Read<uint16_t>();
+ field->ptr()->kind_bits_ = d->Read<uint8_t>();
}
}
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 009dc8c..216bdb5 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -1019,22 +1019,20 @@
while (it.HasNext()) {
cls = it.GetNextClass();
- // Check for @pragma on the class itself.
if (cls.has_pragma()) {
+ // Check for @pragma on the class itself.
metadata ^= lib.GetMetadata(cls);
if (metadata_defines_entrypoint() == EntryPointPragma::kAlways) {
AddInstantiatedClass(cls);
}
- }
- // Check for @pragma on any fields in the class.
- members = cls.fields();
- implicit_getters = GrowableObjectArray::New(members.Length());
- implicit_setters = GrowableObjectArray::New(members.Length());
- implicit_static_getters = GrowableObjectArray::New(members.Length());
- for (intptr_t k = 0; k < members.Length(); ++k) {
- field ^= members.At(k);
- if (field.has_pragma()) {
+ // Check for @pragma on any fields in the class.
+ members = cls.fields();
+ implicit_getters = GrowableObjectArray::New(members.Length());
+ implicit_setters = GrowableObjectArray::New(members.Length());
+ implicit_static_getters = GrowableObjectArray::New(members.Length());
+ for (intptr_t k = 0; k < members.Length(); ++k) {
+ field ^= members.At(k);
metadata ^= lib.GetMetadata(field);
if (metadata.IsNull()) continue;
EntryPointPragma pragma = metadata_defines_entrypoint();
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 0f4e459..7133e1f 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1188,11 +1188,8 @@
CompileType PolymorphicInstanceCallInstr::ComputeType() const {
if (IsSureToCallSingleRecognizedTarget()) {
const Function& target = *targets_.TargetAt(0)->target;
- if (target.has_pragma()) {
- const intptr_t cid = MethodRecognizer::ResultCidFromPragma(target);
- if (cid != kDynamicCid) {
- return CompileType::FromCid(cid);
- }
+ if (target.recognized_kind() != MethodRecognizer::kUnknown) {
+ return CompileType::FromCid(MethodRecognizer::ResultCid(target));
}
}
@@ -1214,11 +1211,8 @@
return *inferred_type;
}
- if (function_.has_pragma()) {
- const intptr_t cid = MethodRecognizer::ResultCidFromPragma(function_);
- if (cid != kDynamicCid) {
- return CompileType::FromCid(cid);
- }
+ if (function_.recognized_kind() != MethodRecognizer::kUnknown) {
+ return CompileType::FromCid(MethodRecognizer::ResultCid(function_));
}
const Isolate* isolate = Isolate::Current();
@@ -1332,15 +1326,8 @@
return CompileType::Dynamic();
}
- bool is_nullable = CompileType::kNullable;
- if (field_ != nullptr && field_->has_pragma()) {
- const intptr_t cid = MethodRecognizer::ResultCidFromPragma(*field_);
- if (cid != kDynamicCid) {
- return CompileType::FromCid(cid);
- }
- }
-
const Isolate* isolate = Isolate::Current();
+ bool is_nullable = CompileType::kNullable;
intptr_t cid = kDynamicCid;
const AbstractType* abstract_type = NULL;
if (isolate->can_use_strong_mode_types() ||
@@ -1353,7 +1340,7 @@
if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid) &&
(field_->guarded_cid() != kDynamicCid)) {
cid = field_->guarded_cid();
- is_nullable = is_nullable && field_->is_nullable();
+ is_nullable = field_->is_nullable();
abstract_type = nullptr; // Cid is known, calculate abstract type lazily.
} else {
cid = result_cid_;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 77ebfa6..4f8b6dd 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1642,30 +1642,25 @@
Fragment StreamingFlowGraphBuilder::BuildEntryPointsIntrospection() {
if (!FLAG_enable_testing_pragmas) return Drop();
- auto& function = Function::Handle(Z, parsed_function()->function().raw());
+ Function& function = Function::Handle(parsed_function()->function().raw());
if (function.IsImplicitClosureFunction()) {
- const auto& parent = Function::Handle(Z, function.parent_function());
- const auto& func_name = String::Handle(Z, parent.name());
- const auto& owner = Class::Handle(Z, parent.Owner());
+ const Function& parent =
+ Function::ZoneHandle(Z, function.parent_function());
+ const String& func_name = String::ZoneHandle(Z, parent.name());
+ const Class& owner = Class::ZoneHandle(Z, parent.Owner());
function = owner.LookupFunction(func_name);
}
- auto& tmp = Object::Handle(Z);
- tmp = function.Owner();
- tmp = Class::Cast(tmp).library();
- auto& library = Library::Cast(tmp);
-
- Object& options = Object::Handle(Z);
- if (!library.FindPragma(H.thread(), function, Symbols::vm_trace_entrypoints(),
- &options) ||
+ Object& options = Object::Handle();
+ if (!function.FindPragma(I, Symbols::vm_trace_entrypoints(), &options) ||
options.IsNull() || !options.IsClosure()) {
return Drop();
}
- auto& closure = Closure::ZoneHandle(Z, Closure::Cast(options).raw());
+ Closure& closure = Closure::ZoneHandle(Z, Closure::Cast(options).raw());
LocalVariable* entry_point_num = MakeTemporary();
- auto& function_name = String::ZoneHandle(
+ String& function_name = String::ZoneHandle(
Z, String::New(function.ToLibNamePrefixedQualifiedCString(), Heap::kOld));
if (parsed_function()->function().IsImplicitClosureFunction()) {
function_name = String::Concat(
@@ -1683,7 +1678,7 @@
call_hook += Constant(Function::ZoneHandle(Z, closure.function()));
call_hook += B->ClosureCall(TokenPosition::kNoSource,
/*type_args_len=*/0, /*argument_count=*/3,
- /*argument_names=*/Array::ZoneHandle(Z));
+ /*argument_names=*/Array::Handle());
call_hook += Drop(); // result of closure call
call_hook += Drop(); // entrypoint number
return call_hook;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index d797a9b..b8b5bff 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -551,8 +551,8 @@
call->set_is_known_list_constructor(true);
return;
}
- if (target.has_pragma()) {
- intptr_t recognized_cid = MethodRecognizer::ResultCidFromPragma(target);
+ if (target.recognized_kind() != MethodRecognizer::kUnknown) {
+ intptr_t recognized_cid = MethodRecognizer::ResultCid(target);
if (recognized_cid != kDynamicCid) {
ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
(result_type->cid == recognized_cid));
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 93f483c..82bf802 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -35,32 +35,20 @@
}
}
-intptr_t MethodRecognizer::ResultCidFromPragma(
- const Object& function_or_field) {
- // TODO(vm-team): The caller should only call us if the
- // function_or_field.has_pragma(). If this method turns out to be a
- // performance problem nonetheless, we could consider adding a cache.
- auto T = Thread::Current();
- auto Z = T->zone();
- bool is_recognized_method = false;
- auto& klass = Class::Handle(Z);
- if (function_or_field.IsFunction()) {
- auto& function = Function::Cast(function_or_field);
- ASSERT(function.has_pragma());
- is_recognized_method =
- function.recognized_kind() != MethodRecognizer::kUnknown;
- klass = function.Owner();
- } else {
- auto& field = Field::Cast(function_or_field);
- ASSERT(field.has_pragma());
- klass = field.Owner();
- }
- auto& library = Library::Handle(Z, klass.library());
- const bool can_use_pragma = library.IsAnyCoreLibrary();
+intptr_t MethodRecognizer::ResultCid(const Function& function) {
+ // Use the 'vm:exact-result-type' annotation if available. This can only be
+ // used within the core library, see 'result_type_pragma.md', detail 1.2 for
+ // explanation.
+ Class& cls = Thread::Current()->ClassHandle();
+ Library& lib = Thread::Current()->LibraryHandle();
+ cls = function.Owner();
+ lib = cls.library();
+ const bool can_use_pragma = lib.IsAnyCoreLibrary();
+ cls = Class::null();
if (can_use_pragma) {
- auto& option = Object::Handle(Z);
- if (library.FindPragma(T, function_or_field,
- Symbols::vm_exact_result_type(), &option)) {
+ Isolate* I = Isolate::Current();
+ auto& option = Object::Handle();
+ if (function.FindPragma(I, Symbols::vm_exact_result_type(), &option)) {
if (option.IsType()) {
return Type::Cast(option).type_class_id();
} else if (option.IsString()) {
@@ -80,13 +68,17 @@
}
}
if (!parse_failure && library_end > 0) {
- auto& tmp = String::Handle(Z);
- tmp = String::SubString(str, 0, library_end, Heap::kOld);
- library = Library::LookupLibrary(Thread::Current(), tmp);
- if (!library.IsNull()) {
- tmp = String::SubString(str, library_end + 1,
- str.Length() - library_end - 1, Heap::kOld);
- klass = library.LookupClassAllowPrivate(tmp);
+ auto& libraryUri = String::Handle(
+ String::SubString(str, 0, library_end, Heap::kOld));
+ auto& className = String::Handle(
+ String::SubString(str, library_end + 1,
+ str.Length() - library_end - 1, Heap::kOld));
+
+ Library& lib = Library::Handle(
+ Library::LookupLibrary(Thread::Current(), libraryUri));
+ if (!lib.IsNull()) {
+ Class& klass =
+ Class::Handle(lib.LookupClassAllowPrivate(className));
if (!klass.IsNull()) {
return klass.id();
}
@@ -96,15 +88,13 @@
}
}
- // Sanity check that all recognized methods which have a non-kDynamicCid were
- // already recognized via @pragmas()s.
- if (FLAG_strong && is_recognized_method) {
- const auto& function = Function::Cast(function_or_field);
- switch (function.recognized_kind()) {
+ // No result-type annotation can be used, so fall back on the table of
+ // recognized methods.
+ switch (function.recognized_kind()) {
#define DEFINE_CASE(cname, fname, ename, result_type, fingerprint) \
case k##ename: { \
const intptr_t cid = k##result_type##Cid; \
- if (cid != kDynamicCid) { \
+ if (FLAG_strong && cid != kDynamicCid) { \
String& err = String::Handle(); \
err = function.QualifiedScrubbedName(); \
err = String::Concat( \
@@ -118,14 +108,11 @@
} \
return cid; \
}
- RECOGNIZED_LIST(DEFINE_CASE)
+ RECOGNIZED_LIST(DEFINE_CASE)
#undef DEFINE_CASE
- default:
- return kDynamicCid;
- }
+ default:
+ return kDynamicCid;
}
-
- return kDynamicCid;
}
intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index f25d177..d53528c 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -560,15 +560,7 @@
static bool AlwaysInline(const Function& function);
static bool PolymorphicTarget(const Function& function);
static intptr_t NumArgsCheckedForStaticCall(const Function& function);
-
- // Try to find an annotation of the form
- // @pragma("vm:exact-result-type", int)
- // @pragma("vm:exact-result-type", "dart:core#_Smi")
- // and return the exact cid if found or kDynamicCid otherwise.
- //
- // See [result_type_pragma.md].
- static intptr_t ResultCidFromPragma(const Object& function_or_field);
-
+ static intptr_t ResultCid(const Function& function);
static intptr_t MethodKindToReceiverCid(Kind kind);
static const char* KindToCString(Kind kind);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index a3a90e1..e3dd575 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5048,7 +5048,7 @@
"because it was not annotated with @pragma('vm:entry-point').\n"
"ERROR: See "
"https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/"
- "aot/entry_point_pragma.md\n",
+ "aot/entry_point_pragma.md",
String::Handle(klass.UserVisibleName()).ToCString());
UNREACHABLE();
}
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 324fb2e..9fb8cfd 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -6,7 +6,6 @@
#include "vm/compiler/frontend/constant_evaluator.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
-#include "vm/compiler/jit/compiler.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/parser.h" // For Parser::kParameter* constants.
@@ -453,11 +452,6 @@
RawObject* EvaluateMetadata(const Field& metadata_field,
bool is_annotations_offset) {
- if (Compiler::IsBackgroundCompilation()) {
- Compiler::AbortBackgroundCompilation(
- DeoptId::kNone, "Cannot evaluate annotations in background compiler.");
- }
-
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* thread = Thread::Current();
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index b68203a..6a818a9 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -953,6 +953,9 @@
ReadVMAnnotations(annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
+ if (has_pragma_annotation) {
+ toplevel_class.set_has_pragma(true);
+ }
field_helper.SetJustRead(FieldHelper::kAnnotations);
field_helper.ReadUntilExcluding(FieldHelper::kType);
@@ -966,7 +969,6 @@
Field::NewTopLevel(name, is_final, field_helper.IsConst(), script_class,
field_helper.position_, field_helper.end_position_));
field.set_kernel_offset(field_offset);
- field.set_has_pragma(has_pragma_annotation);
const AbstractType& type = T.BuildType(); // read type.
field.SetFieldType(type);
ReadInferredType(field, field_offset + library_kernel_offset_);
@@ -1342,6 +1344,9 @@
ReadVMAnnotations(annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
+ if (has_pragma_annotation) {
+ klass.set_has_pragma(true);
+ }
field_helper.SetJustRead(FieldHelper::kAnnotations);
field_helper.ReadUntilExcluding(FieldHelper::kType);
@@ -1361,7 +1366,6 @@
field_helper.IsConst(), is_reflectable, script_class, type,
field_helper.position_, field_helper.end_position_));
field.set_kernel_offset(field_offset);
- field.set_has_pragma(has_pragma_annotation);
ReadInferredType(field, field_offset + library_kernel_offset_);
CheckForInitializer(field);
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ea2e5c4..091451f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2914,40 +2914,27 @@
return result.raw();
}
-bool Library::FindPragma(Thread* T,
- const Object& obj,
- const String& pragma_name,
- Object* options) const {
- auto I = T->isolate();
- auto Z = T->zone();
- auto& lib = Library::Handle(Z);
- if (obj.IsClass()) {
- auto& klass = Class::Cast(obj);
- if (!klass.has_pragma()) return false;
- lib = klass.library();
- } else if (obj.IsFunction()) {
- auto& function = Function::Cast(obj);
- if (!function.has_pragma()) return false;
- lib = Class::Handle(Z, function.Owner()).library();
- } else if (obj.IsField()) {
- auto& field = Field::Cast(obj);
- if (!field.has_pragma()) return false;
- lib = Class::Handle(Z, field.Owner()).library();
- } else {
- UNREACHABLE();
- }
+bool Function::FindPragma(Isolate* I,
+ const String& pragma_name,
+ Object* options) const {
+ if (!has_pragma()) return false;
- Object& metadata_obj = Object::Handle(Z, lib.GetMetadata(obj));
- if (metadata_obj.IsNull() || !metadata_obj.IsArray()) return false;
+ auto& klass = Class::Handle(Owner());
+ auto& lib = Library::Handle(klass.library());
- auto& metadata = Array::Cast(metadata_obj);
- auto& pragma_class = Class::Handle(Z, I->object_store()->pragma_class());
+ auto& pragma_class =
+ Class::Handle(Isolate::Current()->object_store()->pragma_class());
auto& pragma_name_field =
- Field::Handle(Z, pragma_class.LookupField(Symbols::name()));
+ Field::Handle(pragma_class.LookupField(Symbols::name()));
auto& pragma_options_field =
- Field::Handle(Z, pragma_class.LookupField(Symbols::options()));
+ Field::Handle(pragma_class.LookupField(Symbols::options()));
- auto& pragma = Object::Handle(Z);
+ Array& metadata = Array::Handle();
+ metadata ^= lib.GetMetadata(Function::Handle(raw()));
+
+ if (metadata.IsNull()) return false;
+
+ auto& pragma = Object::Handle();
for (intptr_t i = 0; i < metadata.Length(); ++i) {
pragma = metadata.At(i);
if (pragma.clazz() != pragma_class.raw() ||
@@ -8706,7 +8693,6 @@
const Object& owner,
TokenPosition token_pos,
TokenPosition end_token_pos) {
- result.set_kind_bits(0);
result.set_name(name);
result.set_is_static(is_static);
if (!is_static) {
@@ -8723,7 +8709,6 @@
result.set_is_unboxing_candidate(true);
result.set_initializer_changed_after_initialization(false);
result.set_kernel_offset(0);
- result.set_has_pragma(false);
result.set_static_type_exactness_state(
StaticTypeExactnessState::NotTracking());
Isolate* isolate = Isolate::Current();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 70164b9..b58ee61 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2274,6 +2274,8 @@
// Return true if any parent function of this function is generic.
bool HasGenericParent() const;
+ bool FindPragma(Isolate* I, const String& pragma_name, Object* options) const;
+
// Not thread-safe; must be called in the main thread.
// Sets function's code and code's function.
void InstallOptimizedCode(const Code& code) const;
@@ -3216,13 +3218,6 @@
value, raw_ptr()->kind_bits_));
}
- bool has_pragma() const {
- return HasPragmaBit::decode(raw_ptr()->kind_bits_);
- }
- void set_has_pragma(bool value) const {
- set_kind_bits(HasPragmaBit::update(value, raw_ptr()->kind_bits_));
- }
-
intptr_t kernel_offset() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return 0;
@@ -3480,24 +3475,22 @@
kReflectableBit,
kDoubleInitializedBit,
kInitializerChangedAfterInitializatonBit,
- kHasPragmaBit,
};
- class ConstBit : public BitField<uint16_t, bool, kConstBit, 1> {};
- class StaticBit : public BitField<uint16_t, bool, kStaticBit, 1> {};
- class FinalBit : public BitField<uint16_t, bool, kFinalBit, 1> {};
+ class ConstBit : public BitField<uint8_t, bool, kConstBit, 1> {};
+ class StaticBit : public BitField<uint8_t, bool, kStaticBit, 1> {};
+ class FinalBit : public BitField<uint8_t, bool, kFinalBit, 1> {};
class HasInitializerBit
- : public BitField<uint16_t, bool, kHasInitializerBit, 1> {};
+ : public BitField<uint8_t, bool, kHasInitializerBit, 1> {};
class UnboxingCandidateBit
- : public BitField<uint16_t, bool, kUnboxingCandidateBit, 1> {};
- class ReflectableBit : public BitField<uint16_t, bool, kReflectableBit, 1> {};
+ : public BitField<uint8_t, bool, kUnboxingCandidateBit, 1> {};
+ class ReflectableBit : public BitField<uint8_t, bool, kReflectableBit, 1> {};
class DoubleInitializedBit
- : public BitField<uint16_t, bool, kDoubleInitializedBit, 1> {};
+ : public BitField<uint8_t, bool, kDoubleInitializedBit, 1> {};
class InitializerChangedAfterInitializatonBit
- : public BitField<uint16_t,
+ : public BitField<uint8_t,
bool,
kInitializerChangedAfterInitializatonBit,
1> {};
- class HasPragmaBit : public BitField<uint16_t, bool, kHasPragmaBit, 1> {};
// Update guarded cid and guarded length for this field. Returns true, if
// deoptimization of dependent code is required.
@@ -3530,7 +3523,7 @@
void set_end_token_pos(TokenPosition token_pos) const {
StoreNonPointer(&raw_ptr()->end_token_pos_, token_pos);
}
- void set_kind_bits(uint16_t value) const {
+ void set_kind_bits(uint8_t value) const {
StoreNonPointer(&raw_ptr()->kind_bits_, value);
}
@@ -3820,11 +3813,6 @@
const Function& to_fun) const;
RawObject* GetMetadata(const Object& obj) const;
- bool FindPragma(Thread* T,
- const Object& object,
- const String& pragma_name,
- Object* options) const;
-
RawClass* toplevel_class() const { return raw_ptr()->toplevel_class_; }
void set_toplevel_class(const Class& value) const;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index cdb5d63..a617d89 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1218,7 +1218,7 @@
// field.
int8_t static_type_exactness_state_;
- uint16_t kind_bits_; // static, final, const, has initializer....
+ uint8_t kind_bits_; // static, final, const, has initializer....
friend class CidRewriteVisitor;
};