Index: runtime/vm/stub_code.cc |
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc |
index b942c1735f6faa31aa8be92e2db8ceeae75841a6..662306ef481f260fe89c2dc338b66a27a8387055 100644 |
--- a/runtime/vm/stub_code.cc |
+++ b/runtime/vm/stub_code.cc |
@@ -8,6 +8,7 @@ |
#include "vm/assembler.h" |
#include "vm/disassembler.h" |
#include "vm/flags.h" |
+#include "vm/symbols.h" |
#include "vm/virtual_memory.h" |
#include "vm/visitor.h" |
@@ -154,6 +155,50 @@ RawCode* StubCode::Generate(const char* name, |
} |
+static const char* CreateMethodExtractorName(const Function& closure_function) { |
+ const char* kFormat = "[MethodExtractor:%s]"; |
+ const char* function_name = |
+ String::Handle(closure_function.name()).ToCString(); |
+ intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name) + 1; |
+ char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
+ OS::SNPrint(chars, len, kFormat, function_name); |
+ return chars; |
+} |
+ |
+ |
+RawFunction* StubCode::GetMethodExtractor(const Function& closure_function) { |
+ Function& extractor = Function::Handle(closure_function.method_extractor()); |
+ if (extractor.IsNull()) { |
+ Assembler assembler; |
+ |
+ const char* name = CreateMethodExtractorName(closure_function); |
+ |
+ StubCode::GenerateMethodExtractor(&assembler, closure_function); |
+ const Code& code = Code::Handle(Code::FinalizeCode(name, &assembler)); |
+ if (FLAG_disassemble_stubs) { |
+ OS::Print("Code for stub '%s': {\n", name); |
+ Disassembler::Disassemble(code.EntryPoint(), |
+ code.EntryPoint() + assembler.CodeSize()); |
+ OS::Print("}\n"); |
+ } |
+ |
+ const Class& cls = |
+ Class::Handle(Type::Handle(Type::Function()).type_class()); |
+ extractor ^= Function::New(String::Handle(Symbols::New(name)), |
+ RawFunction::kMethodExtractor, |
+ false, // Not static. |
+ false, // Not const. |
+ false, // Not abstract. |
+ false, // Not external. |
+ cls, |
+ 0); // No token position. |
+ extractor.SetCode(code); |
+ extractor.set_extracted_method_closure(closure_function); |
+ } |
+ return extractor.raw(); |
+} |
+ |
+ |
const char* StubCode::NameOfStub(uword entry_point) { |
#define STUB_CODE_TESTER(name) \ |
if ((name##_entry() != NULL) && (entry_point == name##EntryPoint())) { \ |