Skip to content

Commit

Permalink
[vm] Don't use a fuzzy lookup for recognized methods.
Browse files Browse the repository at this point in the history
TEST=ci
Bug: #56007
Change-Id: I30debb6b9c9890739cc1b25b7b2c097551b4c2aa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/374200
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
  • Loading branch information
rmacnak-google authored and Commit Queue committed Jul 8, 2024
1 parent e4e06c6 commit 1dbb56c
Show file tree
Hide file tree
Showing 12 changed files with 789 additions and 707 deletions.
4 changes: 2 additions & 2 deletions runtime/vm/compiler/aot/precompiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3846,7 +3846,7 @@ void Obfuscator::InitializeRenamingMap() {
// Prevent renaming of methods that are looked up by method recognizer.
// TODO(dartbug.com/30524) instead call to Obfuscator::Rename from a place
// where these are looked up.
#define PREVENT_RENAMING(class_name, function_name, recognized_enum, \
#define PREVENT_RENAMING(library, class_name, function_name, recognized_enum, \
fingerprint) \
do { \
PreventRenaming(#class_name); \
Expand All @@ -3858,7 +3858,7 @@ void Obfuscator::InitializeRenamingMap() {
// Prevent renaming of methods that are looked up by method recognizer.
// TODO(dartbug.com/30524) instead call to Obfuscator::Rename from a place
// where these are looked up.
#define PREVENT_RENAMING(class_name, function_name, recognized_enum, \
#define PREVENT_RENAMING(libary, class_name, function_name, recognized_enum, \
fingerprint) \
do { \
PreventRenaming(#class_name); \
Expand Down
2 changes: 1 addition & 1 deletion runtime/vm/compiler/asm_intrinsifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class AsmIntrinsifier : public AllStatic {
private:
friend class Intrinsifier;

#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp) \
#define DECLARE_FUNCTION(library, class, function, enum_name, fp) \
static void enum_name(Assembler* assembler, Label* normal_ir_body);
ALL_INTRINSICS_LIST(DECLARE_FUNCTION)

Expand Down
2 changes: 1 addition & 1 deletion runtime/vm/compiler/graph_intrinsifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool GraphIntrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
const Function& function = parsed_function.function();

switch (function.recognized_kind()) {
#define EMIT_CASE(class_name, function_name, enum_name, fp) \
#define EMIT_CASE(library, class_name, function_name, enum_name, fp) \
case MethodRecognizer::k##enum_name: \
if (!Build_##enum_name(graph)) return false; \
break;
Expand Down
4 changes: 2 additions & 2 deletions runtime/vm/compiler/graph_intrinsifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ class GraphIntrinsifier : public AllStatic {
FlowGraphCompiler* compiler);

private:
#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp) \
#define DECLARE_FUNCTION(library, class, function, enum_name, fp) \
static void enum_name(Assembler* assembler, Label* normal_ir_body);

GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)

#undef DECLARE_FUNCTION

#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp) \
#define DECLARE_FUNCTION(library, class, function, enum_name, fp) \
static bool Build_##enum_name(FlowGraph* flow_graph);

GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
Expand Down
96 changes: 1 addition & 95 deletions runtime/vm/compiler/intrinsifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,100 +75,6 @@ bool Intrinsifier::CanIntrinsify(const ParsedFunction& parsed_function) {
return true;
}

struct IntrinsicDesc {
const char* class_name;
const char* function_name;
};

struct LibraryIntrinsicsDesc {
Library& library;
const IntrinsicDesc* intrinsics;
};

#define DEFINE_INTRINSIC(class_name, function_name, destination, fp) \
{#class_name, #function_name},

// clang-format off
static const IntrinsicDesc core_intrinsics[] = {
CORE_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
CORE_INTEGER_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
GRAPH_CORE_INTRINSICS_LIST(DEFINE_INTRINSIC)
{nullptr, nullptr},
};

static const IntrinsicDesc typed_data_intrinsics[] = {
GRAPH_TYPED_DATA_INTRINSICS_LIST(DEFINE_INTRINSIC)
{nullptr, nullptr},
};

static const IntrinsicDesc developer_intrinsics[] = {
DEVELOPER_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
{nullptr, nullptr},
};

static const IntrinsicDesc internal_intrinsics[] = {
INTERNAL_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
{nullptr, nullptr},
};
// clang-format on

void Intrinsifier::InitializeState() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Library& lib = Library::Handle(zone);
Class& cls = Class::Handle(zone);
Function& func = Function::Handle(zone);
String& str = String::Handle(zone);
String& str2 = String::Handle(zone);
Error& error = Error::Handle(zone);

const intptr_t kNumLibs = 4;
const LibraryIntrinsicsDesc intrinsics[kNumLibs] = {
{Library::Handle(zone, Library::CoreLibrary()), core_intrinsics},
{Library::Handle(zone, Library::TypedDataLibrary()),
typed_data_intrinsics},
{Library::Handle(zone, Library::DeveloperLibrary()),
developer_intrinsics},
{Library::Handle(zone, Library::InternalLibrary()), internal_intrinsics},
};

for (intptr_t i = 0; i < kNumLibs; i++) {
lib = intrinsics[i].library.ptr();
for (const IntrinsicDesc* intrinsic = intrinsics[i].intrinsics;
intrinsic->class_name != nullptr; intrinsic++) {
func = Function::null();
if (strcmp(intrinsic->class_name, "::") == 0) {
str = String::New(intrinsic->function_name);
func = lib.LookupFunctionAllowPrivate(str);
} else {
str = String::New(intrinsic->class_name);
cls = lib.LookupClassAllowPrivate(str);
ASSERT(FLAG_precompiled_mode || !cls.IsNull());
if (!cls.IsNull()) {
error = cls.EnsureIsFinalized(thread);
if (!error.IsNull()) {
OS::PrintErr("%s\n", error.ToErrorCString());
}
ASSERT(error.IsNull());
str = String::New(intrinsic->function_name);
if (intrinsic->function_name[0] == '.') {
str2 = String::New(intrinsic->class_name);
str = String::Concat(str2, str);
}
func = cls.LookupFunctionAllowPrivate(str);
}
}
if (!func.IsNull()) {
func.set_is_intrinsic(true);
} else if (!FLAG_precompiled_mode) {
FATAL("Intrinsifier failed to find method %s in class %s\n",
intrinsic->function_name, intrinsic->class_name);
}
}
}
#undef SETUP_FUNCTION
}

// Returns true if fall-through code can be omitted.
bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
FlowGraphCompiler* compiler) {
Expand Down Expand Up @@ -197,7 +103,7 @@ bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
#define EMIT_BREAKPOINT()
#endif

#define EMIT_CASE(class_name, function_name, enum_name, fp) \
#define EMIT_CASE(library, class_name, function_name, enum_name, fp) \
case MethodRecognizer::k##enum_name: { \
compiler->assembler()->Comment("Intrinsic"); \
Label normal_ir_body; \
Expand Down
2 changes: 0 additions & 2 deletions runtime/vm/compiler/intrinsifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ class Intrinsifier : public AllStatic {
static bool Intrinsify(const ParsedFunction& parsed_function,
FlowGraphCompiler* compiler);

static void InitializeState();

private:
static bool CanIntrinsify(const ParsedFunction& parsed_function);
};
Expand Down
72 changes: 40 additions & 32 deletions runtime/vm/compiler/method_recognizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static const struct {
const uint32_t fp;
} recognized_methods[MethodRecognizer::kNumRecognizedMethods] = {
{"", "", "Unknown", 0},
#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp) \
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp) \
{"" #class_name, "" #function_name, #enum_name, fp},
RECOGNIZED_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
Expand Down Expand Up @@ -160,40 +160,46 @@ bool MethodRecognizer::IsMarkedAsRecognized(const Function& function,
return String::Cast(options).Equals(kind);
}

static bool IsIntrinsic(MethodRecognizer::Kind kind) {
switch (kind) {
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp) \
case MethodRecognizer::k##enum_name: \
ALL_INTRINSICS_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
return true;
default:
return false;
}
}

void MethodRecognizer::InitializeState() {
GrowableArray<Library*> libs(3);
Libraries(&libs);
Library& lib = Library::Handle();
Function& func = Function::Handle();
bool fingerprints_match = true;

for (intptr_t i = 1; i < MethodRecognizer::kNumRecognizedMethods; i++) {
const MethodRecognizer::Kind kind = static_cast<MethodRecognizer::Kind>(i);
func = Library::GetFunction(libs, recognized_methods[i].class_name,
recognized_methods[i].function_name);
if (!func.IsNull()) {
fingerprints_match =
func.CheckSourceFingerprint(recognized_methods[i].fp) &&
fingerprints_match;
func.set_recognized_kind(kind);
switch (kind) {
#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp) \
case MethodRecognizer::k##enum_name: \
func.reset_unboxed_parameters_and_return(); \
break;
ALL_INTRINSICS_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
default:
break;
}
} else if (!FLAG_precompiled_mode) {
fingerprints_match = false;
OS::PrintErr("Missing %s::%s\n", recognized_methods[i].class_name,
recognized_methods[i].function_name);
}
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp) \
lib = Library::library(); \
func = Library::GetFunction(lib, #class_name, #function_name); \
if (!func.IsNull()) { \
fingerprints_match = \
func.CheckSourceFingerprint(fp) && fingerprints_match; \
func.set_recognized_kind(k##enum_name); \
if (IsIntrinsic(k##enum_name)) { \
func.reset_unboxed_parameters_and_return(); \
func.set_is_intrinsic(true); \
} \
} else if (!FLAG_precompiled_mode) { \
fingerprints_match = false; \
OS::PrintErr("Missing %s %s::%s\n", #library, #class_name, \
#function_name); \
}
RECOGNIZED_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD

#define SET_FUNCTION_BIT(class_name, function_name, dest, fp, setter, value) \
func = Library::GetFunction(libs, #class_name, #function_name); \
#define SET_FUNCTION_BIT(library, class_name, function_name, dest, fp, setter, \
value) \
lib = Library::library(); \
func = Library::GetFunction(lib, #class_name, #function_name); \
if (!func.IsNull()) { \
fingerprints_match = \
func.CheckSourceFingerprint(fp) && fingerprints_match; \
Expand All @@ -203,8 +209,9 @@ void MethodRecognizer::InitializeState() {
fingerprints_match = false; \
}

#define SET_IS_POLYMORPHIC_TARGET(class_name, function_name, dest, fp) \
SET_FUNCTION_BIT(class_name, function_name, dest, fp, \
#define SET_IS_POLYMORPHIC_TARGET(library, class_name, function_name, dest, \
fp) \
SET_FUNCTION_BIT(library, class_name, function_name, dest, fp, \
set_is_polymorphic_target, true)

POLYMORPHIC_TARGET_LIST(SET_IS_POLYMORPHIC_TARGET);
Expand Down Expand Up @@ -299,7 +306,8 @@ Token::Kind MethodTokenRecognizer::RecognizeTokenKind(const String& name) {
}
}

#define RECOGNIZE_FACTORY(symbol, class_name, constructor_name, cid, fp) \
#define RECOGNIZE_FACTORY(symbol, library, class_name, constructor_name, cid, \
fp) \
{Symbols::k##symbol##Id, cid, fp, #symbol ", " #cid}, // NOLINT

static const struct {
Expand Down
2 changes: 1 addition & 1 deletion runtime/vm/compiler/method_recognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class MethodRecognizer : public AllStatic {
public:
enum Kind {
kUnknown,
#define DEFINE_ENUM_LIST(class_name, function_name, enum_name, fp) k##enum_name,
#define DEFINE_ENUM_LIST(library, class, function, enum_name, fp) k##enum_name,
RECOGNIZED_LIST(DEFINE_ENUM_LIST)
#undef DEFINE_ENUM_LIST
kNumRecognizedMethods
Expand Down
Loading

0 comments on commit 1dbb56c

Please sign in to comment.