Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: runtime/vm/kernel_reader.cc

Issue 2820363002: Move Kernel strings into the VM's heap. (Closed)
Patch Set: Incorporate review comments. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel_reader.h ('k') | runtime/vm/kernel_to_il.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/kernel_reader.h" 5 #include "vm/kernel_reader.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 #include "vm/symbols.h" 13 #include "vm/symbols.h"
14 14
15 #if !defined(DART_PRECOMPILED_RUNTIME) 15 #if !defined(DART_PRECOMPILED_RUNTIME)
16 namespace dart { 16 namespace dart {
17 namespace kernel { 17 namespace kernel {
18 18
19 #define Z (zone_) 19 #define Z (zone_)
20 #define I (isolate_) 20 #define I (isolate_)
21 #define T (type_translator_) 21 #define T (type_translator_)
22 #define H (translation_helper_) 22 #define H (translation_helper_)
23 23
24 class SimpleExpressionConverter : public ExpressionVisitor { 24 class SimpleExpressionConverter : public ExpressionVisitor {
25 public: 25 public:
26 explicit SimpleExpressionConverter(Thread* thread) 26 explicit SimpleExpressionConverter(TranslationHelper* helper)
27 : translation_helper_(thread), 27 : translation_helper_(*helper),
28 zone_(translation_helper_.zone()), 28 zone_(translation_helper_.zone()),
29 is_simple_(false), 29 is_simple_(false),
30 simple_value_(NULL) {} 30 simple_value_(NULL) {}
31 31
32 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; } 32 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; }
33 33
34 virtual void VisitIntLiteral(IntLiteral* node) { 34 virtual void VisitIntLiteral(IntLiteral* node) {
35 is_simple_ = true; 35 is_simple_ = true;
36 simple_value_ = 36 simple_value_ =
37 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld)); 37 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 bool IsSimple(Expression* expression) { 70 bool IsSimple(Expression* expression) {
71 expression->AcceptExpressionVisitor(this); 71 expression->AcceptExpressionVisitor(this);
72 return is_simple_; 72 return is_simple_;
73 } 73 }
74 74
75 const dart::Instance& SimpleValue() { return *simple_value_; } 75 const dart::Instance& SimpleValue() { return *simple_value_; }
76 dart::Zone* zone() const { return zone_; } 76 dart::Zone* zone() const { return zone_; }
77 77
78 private: 78 private:
79 TranslationHelper translation_helper_; 79 TranslationHelper& translation_helper_;
80 dart::Zone* zone_; 80 dart::Zone* zone_;
81 bool is_simple_; 81 bool is_simple_;
82 dart::Instance* simple_value_; 82 dart::Instance* simple_value_;
83 }; 83 };
84 84
85 85
86 RawArray* KernelReader::MakeFunctionsArray() { 86 RawArray* KernelReader::MakeFunctionsArray() {
87 const intptr_t len = functions_.length(); 87 const intptr_t len = functions_.length();
88 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); 88 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
89 for (intptr_t i = 0; i < len; i++) { 89 for (intptr_t i = 0; i < len; i++) {
90 res.SetAt(i, *functions_[i]); 90 res.SetAt(i, *functions_[i]);
91 } 91 }
92 return res.raw(); 92 return res.raw();
93 } 93 }
94 94
95 95
96 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary( 96 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary(
97 CanonicalName* library) { 97 CanonicalName* library) {
98 return reader_->LookupLibrary(library).raw(); 98 return reader_->LookupLibrary(library).raw();
99 } 99 }
100 100
101 101
102 RawClass* BuildingTranslationHelper::LookupClassByKernelClass( 102 RawClass* BuildingTranslationHelper::LookupClassByKernelClass(
103 CanonicalName* klass) { 103 CanonicalName* klass) {
104 return reader_->LookupClass(klass).raw(); 104 return reader_->LookupClass(klass).raw();
105 } 105 }
106 106
107
107 KernelReader::KernelReader(Program* program) 108 KernelReader::KernelReader(Program* program)
108 : program_(program), 109 : program_(program),
109 thread_(dart::Thread::Current()), 110 thread_(dart::Thread::Current()),
110 zone_(thread_->zone()), 111 zone_(thread_->zone()),
111 isolate_(thread_->isolate()), 112 isolate_(thread_->isolate()),
112 scripts_(Array::ZoneHandle(zone_)), 113 scripts_(Array::ZoneHandle(zone_)),
113 translation_helper_(this, thread_), 114 translation_helper_(this, thread_),
114 type_translator_(&translation_helper_, 115 type_translator_(&translation_helper_,
115 &active_class_, 116 &active_class_,
116 /*finalize=*/false) { 117 /*finalize=*/false) {
117 intptr_t source_file_count = program_->source_table().size(); 118 intptr_t source_file_count = program->source_table().size();
118 scripts_ = Array::New(source_file_count, Heap::kOld); 119 scripts_ = Array::New(source_file_count, Heap::kOld);
120
121 // Copy the Kernel strings out of the binary and into the VM's heap. The size
122 // of the string data can be computed from the offset and size of the last
123 // string. This relies on the strings occurring in order in the program's
124 // string table.
125 List<String>& strings = program->string_table().strings();
126 String* last_string = strings[strings.length() - 1];
127 intptr_t size = last_string->offset() + last_string->size();
128 TypedData& data = TypedData::Handle(
129 Z, TypedData::New(kTypedDataUint8ArrayCid, size, Heap::kOld));
130 ASSERT(program->string_data_offset() >= 0);
131 // We need at least one library to get access to the binary.
132 ASSERT(program->libraries().length() > 0);
133 {
134 NoSafepointScope no_safepoint;
135 memmove(data.DataAddr(0), program->libraries()[0]->kernel_data() +
136 program->string_data_offset(),
137 size);
138 }
139 H.SetStringData(data);
119 } 140 }
120 141
142
121 Object& KernelReader::ReadProgram() { 143 Object& KernelReader::ReadProgram() {
122 LongJumpScope jump; 144 LongJumpScope jump;
123 if (setjmp(*jump.Set()) == 0) { 145 if (setjmp(*jump.Set()) == 0) {
124 intptr_t length = program_->libraries().length(); 146 intptr_t length = program_->libraries().length();
125 for (intptr_t i = 0; i < length; i++) { 147 for (intptr_t i = 0; i < length; i++) {
126 Library* kernel_library = program_->libraries()[i]; 148 Library* kernel_library = program_->libraries()[i];
127 ReadLibrary(kernel_library); 149 ReadLibrary(kernel_library);
128 } 150 }
129 151
130 for (intptr_t i = 0; i < length; i++) { 152 for (intptr_t i = 0; i < length; i++) {
131 dart::Library& library = 153 dart::Library& library =
132 LookupLibrary(program_->libraries()[i]->canonical_name()); 154 LookupLibrary(program_->libraries()[i]->canonical_name());
133 if (!library.Loaded()) library.SetLoaded(); 155 if (!library.Loaded()) library.SetLoaded();
134 } 156 }
135 157
136 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { 158 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) {
137 CanonicalName* main = program_->main_method(); 159 CanonicalName* main = program_->main_method();
138 dart::Library& library = LookupLibrary(main->EnclosingName()); 160 dart::Library& library = LookupLibrary(H.EnclosingName(main));
139 161
140 // Sanity check that we can find the main entrypoint. 162 // Sanity check that we can find the main entrypoint.
141 Object& main_obj = Object::Handle( 163 Object& main_obj = Object::Handle(
142 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main"))); 164 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main")));
143 ASSERT(!main_obj.IsNull()); 165 ASSERT(!main_obj.IsNull());
144 return library; 166 return library;
145 } 167 }
146 } 168 }
147 169
148 // Either class finalization failed or we caught a compile error. 170 // Either class finalization failed or we caught a compile error.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 dart::String* native_name = NULL; 443 dart::String* native_name = NULL;
422 if (is_external) { 444 if (is_external) {
423 // Maybe it has a native implementation, which is not external as far as 445 // Maybe it has a native implementation, which is not external as far as
424 // the VM is concerned because it does have an implementation. Check for 446 // the VM is concerned because it does have an implementation. Check for
425 // an ExternalName annotation and extract the string from it. 447 // an ExternalName annotation and extract the string from it.
426 for (int i = 0; i < kernel_procedure->annotations().length(); ++i) { 448 for (int i = 0; i < kernel_procedure->annotations().length(); ++i) {
427 Expression* annotation = kernel_procedure->annotations()[i]; 449 Expression* annotation = kernel_procedure->annotations()[i];
428 if (!annotation->IsConstructorInvocation()) continue; 450 if (!annotation->IsConstructorInvocation()) continue;
429 ConstructorInvocation* invocation = 451 ConstructorInvocation* invocation =
430 ConstructorInvocation::Cast(annotation); 452 ConstructorInvocation::Cast(annotation);
431 CanonicalName* annotation_class = invocation->target()->EnclosingName(); 453 CanonicalName* annotation_class = H.EnclosingName(invocation->target());
432 ASSERT(annotation_class->IsClass()); 454 ASSERT(H.IsClass(annotation_class));
433 String* class_name = annotation_class->name(); 455 String* class_name = annotation_class->name();
434 // Just compare by name, do not generate the annotation class. 456 // Just compare by name, do not generate the annotation class.
435 int length = sizeof("ExternalName") - 1; 457 if (!H.StringEquals(class_name, "ExternalName")) continue;
436 if (class_name->size() != length) continue; 458 ASSERT(H.IsLibrary(annotation_class->parent()));
437 if (memcmp(class_name->buffer(), "ExternalName", length) != 0) continue;
438 ASSERT(annotation_class->parent()->IsLibrary());
439 String* library_name = annotation_class->parent()->name(); 459 String* library_name = annotation_class->parent()->name();
440 length = sizeof("dart:_internal") - 1; 460 if (!H.StringEquals(library_name, "dart:_internal")) continue;
441 if (library_name->size() != length) continue;
442 if (memcmp(library_name->buffer(), "dart:_internal", length) != 0) {
443 continue;
444 }
445 461
446 is_external = false; 462 is_external = false;
447 ASSERT(invocation->arguments()->positional().length() == 1 && 463 ASSERT(invocation->arguments()->positional().length() == 1 &&
448 invocation->arguments()->named().length() == 0); 464 invocation->arguments()->named().length() == 0);
449 StringLiteral* literal = 465 StringLiteral* literal =
450 StringLiteral::Cast(invocation->arguments()->positional()[0]); 466 StringLiteral::Cast(invocation->arguments()->positional()[0]);
451 native_name = &H.DartSymbol(literal->value()); 467 native_name = &H.DartSymbol(literal->value());
452 break; 468 break;
453 } 469 }
454 } 470 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 source->Sort(LowestFirst); 553 source->Sort(LowestFirst);
538 554
539 intptr_t size = source->length(); 555 intptr_t size = source->length();
540 intptr_t last = 0; 556 intptr_t last = 0;
541 for (intptr_t current = 1; current < size; ++current) { 557 for (intptr_t current = 1; current < size; ++current) {
542 if (source->At(last) != source->At(current)) { 558 if (source->At(last) != source->At(current)) {
543 (*source)[++last] = source->At(current); 559 (*source)[++last] = source->At(current);
544 } 560 }
545 } 561 }
546 Array& array_object = Array::Handle(); 562 Array& array_object = Array::Handle();
547 array_object ^= Array::New(last + 1, Heap::kOld); 563 array_object = Array::New(last + 1, Heap::kOld);
548 Smi& smi_value = Smi::Handle(); 564 Smi& smi_value = Smi::Handle();
549 for (intptr_t i = 0; i <= last; ++i) { 565 for (intptr_t i = 0; i <= last; ++i) {
550 smi_value = Smi::New(source->At(i)); 566 smi_value = Smi::New(source->At(i));
551 array_object.SetAt(i, smi_value); 567 array_object.SetAt(i, smi_value);
552 } 568 }
553 return array_object.raw(); 569 return array_object.raw();
554 } else { 570 } else {
555 return Array::New(0); 571 return Array::New(0);
556 } 572 }
557 } 573 }
558 574
559 Script& KernelReader::ScriptAt(intptr_t source_uri_index, String* import_uri) { 575 Script& KernelReader::ScriptAt(intptr_t index, String* import_uri) {
560 Script& script = Script::ZoneHandle(Z); 576 Script& script = Script::ZoneHandle(Z);
561 script ^= scripts_.At(source_uri_index); 577 script ^= scripts_.At(index);
562 if (script.IsNull()) { 578 if (script.IsNull()) {
563 // Create script with correct uri(s). 579 // Create script with correct uri(s).
564 String* uri = program_->source_uri_table().strings()[source_uri_index]; 580 uint8_t* uri_buffer = program_->source_table().UriFor(index);
565 dart::String& uri_string = H.DartString(uri, Heap::kOld); 581 intptr_t uri_size = program_->source_table().UriSizeFor(index);
582 dart::String& uri_string = H.DartString(uri_buffer, uri_size, Heap::kOld);
566 dart::String& import_uri_string = 583 dart::String& import_uri_string =
567 import_uri == NULL ? uri_string : H.DartString(import_uri, Heap::kOld); 584 import_uri == NULL ? uri_string : H.DartString(import_uri, Heap::kOld);
568 dart::String& source_code = H.DartString( 585 uint8_t* source_buffer = program_->source_table().SourceCodeFor(index);
569 program_->source_table().SourceFor(source_uri_index), Heap::kOld); 586 intptr_t source_size = program_->source_table().SourceCodeSizeFor(index);
587 dart::String& source_code =
588 H.DartString(source_buffer, source_size, Heap::kOld);
570 script = Script::New(import_uri_string, uri_string, source_code, 589 script = Script::New(import_uri_string, uri_string, source_code,
571 RawScript::kKernelTag); 590 RawScript::kKernelTag);
572 scripts_.SetAt(source_uri_index, script); 591 script.set_kernel_strings(H.string_data());
592 scripts_.SetAt(index, script);
573 593
574 // Create line_starts array for the script. 594 // Create line_starts array for the script.
575 intptr_t* line_starts = 595 intptr_t* line_starts = program_->source_table().LineStartsFor(index);
576 program_->source_table().LineStartsFor(source_uri_index); 596 intptr_t line_count = program_->source_table().LineCountFor(index);
577 intptr_t line_count =
578 program_->source_table().LineCountFor(source_uri_index);
579 Array& array_object = Array::Handle(Z, Array::New(line_count, Heap::kOld)); 597 Array& array_object = Array::Handle(Z, Array::New(line_count, Heap::kOld));
580 Smi& value = Smi::Handle(Z); 598 Smi& value = Smi::Handle(Z);
581 for (intptr_t i = 0; i < line_count; ++i) { 599 for (intptr_t i = 0; i < line_count; ++i) {
582 value = Smi::New(line_starts[i]); 600 value = Smi::New(line_starts[i]);
583 array_object.SetAt(i, value); 601 array_object.SetAt(i, value);
584 } 602 }
585 script.set_line_starts(array_object); 603 script.set_line_starts(array_object);
586 604
587 // Create tokens_seen array for the script. 605 // Create tokens_seen array for the script.
588 array_object ^= AsSortedDuplicateFreeArray( 606 array_object =
589 source_uri_index, &program_->valid_token_positions); 607 AsSortedDuplicateFreeArray(index, &program_->valid_token_positions);
590 script.set_debug_positions(array_object); 608 script.set_debug_positions(array_object);
591 609
592 // Create yield_positions array for the script. 610 // Create yield_positions array for the script.
593 array_object ^= AsSortedDuplicateFreeArray( 611 array_object =
594 source_uri_index, &program_->yield_token_positions); 612 AsSortedDuplicateFreeArray(index, &program_->yield_token_positions);
595 script.set_yield_positions(array_object); 613 script.set_yield_positions(array_object);
596 } 614 }
597 return script; 615 return script;
598 } 616 }
599 617
600 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, 618 void KernelReader::GenerateFieldAccessors(const dart::Class& klass,
601 const dart::Field& field, 619 const dart::Field& field,
602 Field* kernel_field) { 620 Field* kernel_field) {
603 if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) { 621 if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) {
604 // Static fields without an initializer are implicitly initialized to null. 622 // Static fields without an initializer are implicitly initialized to null.
605 // We do not need a getter. 623 // We do not need a getter.
606 field.SetStaticValue(Instance::Handle(Z), true); 624 field.SetStaticValue(Instance::Handle(Z), true);
607 return; 625 return;
608 } 626 }
609 if (kernel_field->initializer() != NULL) { 627 if (kernel_field->initializer() != NULL) {
610 SimpleExpressionConverter converter(H.thread()); 628 SimpleExpressionConverter converter(&H);
611 const bool has_simple_initializer = 629 const bool has_simple_initializer =
612 converter.IsSimple(kernel_field->initializer()); 630 converter.IsSimple(kernel_field->initializer());
613 if (kernel_field->IsStatic()) { 631 if (kernel_field->IsStatic()) {
614 // Static fields with initializers either have the static value set to the 632 // Static fields with initializers either have the static value set to the
615 // initializer value if it is simple enough or else set to an 633 // initializer value if it is simple enough or else set to an
616 // uninitialized sentinel. 634 // uninitialized sentinel.
617 if (has_simple_initializer) { 635 if (has_simple_initializer) {
618 // We do not need a getter. 636 // We do not need a getter.
619 field.SetStaticValue(converter.SimpleValue(), true); 637 field.SetStaticValue(converter.SimpleValue(), true);
620 return; 638 return;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 initializer_fun.set_is_debuggable(false); 882 initializer_fun.set_is_debuggable(false);
865 initializer_fun.set_is_reflectable(false); 883 initializer_fun.set_is_reflectable(false);
866 initializer_fun.set_is_inlinable(false); 884 initializer_fun.set_is_inlinable(false);
867 return new (zone) ParsedFunction(thread, initializer_fun); 885 return new (zone) ParsedFunction(thread, initializer_fun);
868 } 886 }
869 887
870 888
871 } // namespace kernel 889 } // namespace kernel
872 } // namespace dart 890 } // namespace dart
873 #endif // !defined(DART_PRECOMPILED_RUNTIME) 891 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_reader.h ('k') | runtime/vm/kernel_to_il.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698