OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 6667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6678 intptr_t count = 0; | 6678 intptr_t count = 0; |
6679 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 6679 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
6680 if (deopt_id_to_ic_data[i] != NULL) { | 6680 if (deopt_id_to_ic_data[i] != NULL) { |
6681 count++; | 6681 count++; |
6682 } | 6682 } |
6683 } | 6683 } |
6684 if (count == 0) { | 6684 if (count == 0) { |
6685 set_ic_data_array(Object::empty_array()); | 6685 set_ic_data_array(Object::empty_array()); |
6686 } else { | 6686 } else { |
6687 const Array& a = Array::Handle(Array::New(count, Heap::kOld)); | 6687 const Array& a = Array::Handle(Array::New(count, Heap::kOld)); |
6688 INC_STAT(Isolate::Current(), total_code_size, count * sizeof(uword)); | |
6688 count = 0; | 6689 count = 0; |
6689 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 6690 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
6690 if (deopt_id_to_ic_data[i] != NULL) { | 6691 if (deopt_id_to_ic_data[i] != NULL) { |
6691 a.SetAt(count++, *deopt_id_to_ic_data[i]); | 6692 a.SetAt(count++, *deopt_id_to_ic_data[i]); |
6692 } | 6693 } |
6693 } | 6694 } |
6694 set_ic_data_array(a); | 6695 set_ic_data_array(a); |
6695 } | 6696 } |
6696 } | 6697 } |
6697 | 6698 |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6968 return "RedirectionData class"; | 6969 return "RedirectionData class"; |
6969 } | 6970 } |
6970 | 6971 |
6971 | 6972 |
6972 void RedirectionData::PrintJSONImpl(JSONStream* stream, bool ref) const { | 6973 void RedirectionData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
6973 Object::PrintJSONImpl(stream, ref); | 6974 Object::PrintJSONImpl(stream, ref); |
6974 } | 6975 } |
6975 | 6976 |
6976 | 6977 |
6977 RawString* Field::GetterName(const String& field_name) { | 6978 RawString* Field::GetterName(const String& field_name) { |
6978 CompilerStats::make_accessor_name++; | |
6979 return String::Concat(Symbols::GetterPrefix(), field_name); | 6979 return String::Concat(Symbols::GetterPrefix(), field_name); |
6980 } | 6980 } |
6981 | 6981 |
6982 | 6982 |
6983 RawString* Field::GetterSymbol(const String& field_name) { | 6983 RawString* Field::GetterSymbol(const String& field_name) { |
6984 return Symbols::FromConcat(Symbols::GetterPrefix(), field_name); | 6984 return Symbols::FromConcat(Symbols::GetterPrefix(), field_name); |
6985 } | 6985 } |
6986 | 6986 |
6987 | 6987 |
6988 RawString* Field::SetterName(const String& field_name) { | 6988 RawString* Field::SetterName(const String& field_name) { |
6989 CompilerStats::make_accessor_name++; | |
6990 return String::Concat(Symbols::SetterPrefix(), field_name); | 6989 return String::Concat(Symbols::SetterPrefix(), field_name); |
6991 } | 6990 } |
6992 | 6991 |
6993 | 6992 |
6994 RawString* Field::SetterSymbol(const String& field_name) { | 6993 RawString* Field::SetterSymbol(const String& field_name) { |
6995 return Symbols::FromConcat(Symbols::SetterPrefix(), field_name); | 6994 return Symbols::FromConcat(Symbols::SetterPrefix(), field_name); |
6996 } | 6995 } |
6997 | 6996 |
6998 | 6997 |
6999 RawString* Field::NameFromGetter(const String& getter_name) { | 6998 RawString* Field::NameFromGetter(const String& getter_name) { |
7000 CompilerStats::make_field_name++; | |
7001 return String::SubString(getter_name, strlen(kGetterPrefix)); | 6999 return String::SubString(getter_name, strlen(kGetterPrefix)); |
7002 } | 7000 } |
7003 | 7001 |
7004 | 7002 |
7005 RawString* Field::NameFromSetter(const String& setter_name) { | 7003 RawString* Field::NameFromSetter(const String& setter_name) { |
7006 CompilerStats::make_field_name++; | |
7007 return String::SubString(setter_name, strlen(kSetterPrefix)); | 7004 return String::SubString(setter_name, strlen(kSetterPrefix)); |
7008 } | 7005 } |
7009 | 7006 |
7010 | 7007 |
7011 bool Field::IsGetterName(const String& function_name) { | 7008 bool Field::IsGetterName(const String& function_name) { |
7012 return function_name.StartsWith(Symbols::GetterPrefix()); | 7009 return function_name.StartsWith(Symbols::GetterPrefix()); |
7013 } | 7010 } |
7014 | 7011 |
7015 | 7012 |
7016 bool Field::IsSetterName(const String& function_name) { | 7013 bool Field::IsSetterName(const String& function_name) { |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7948 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens, | 7945 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens, |
7949 const String& private_key) { | 7946 const String& private_key) { |
7950 // Copy the relevant data out of the scanner into a compressed stream of | 7947 // Copy the relevant data out of the scanner into a compressed stream of |
7951 // tokens. | 7948 // tokens. |
7952 CompressedTokenStreamData data; | 7949 CompressedTokenStreamData data; |
7953 intptr_t len = tokens.length(); | 7950 intptr_t len = tokens.length(); |
7954 for (intptr_t i = 0; i < len; i++) { | 7951 for (intptr_t i = 0; i < len; i++) { |
7955 Scanner::TokenDescriptor token = tokens[i]; | 7952 Scanner::TokenDescriptor token = tokens[i]; |
7956 if (token.kind == Token::kIDENT) { // Identifier token. | 7953 if (token.kind == Token::kIDENT) { // Identifier token. |
7957 if (FLAG_compiler_stats) { | 7954 if (FLAG_compiler_stats) { |
7958 CompilerStats::num_ident_tokens_total += 1; | 7955 INC_STAT(Isolate::Current(), num_ident_tokens_total, 1); |
7959 } | 7956 } |
7960 data.AddIdentToken(token.literal); | 7957 data.AddIdentToken(token.literal); |
7961 } else if (Token::NeedsLiteralToken(token.kind)) { // Literal token. | 7958 } else if (Token::NeedsLiteralToken(token.kind)) { // Literal token. |
7962 if (FLAG_compiler_stats) { | 7959 if (FLAG_compiler_stats) { |
7963 CompilerStats::num_literal_tokens_total += 1; | 7960 INC_STAT(Isolate::Current(), num_literal_tokens_total, 1); |
7964 } | 7961 } |
7965 data.AddLiteralToken(token); | 7962 data.AddLiteralToken(token); |
7966 } else { // Keyword, pseudo keyword etc. | 7963 } else { // Keyword, pseudo keyword etc. |
7967 ASSERT(token.kind < Token::kNumTokens); | 7964 ASSERT(token.kind < Token::kNumTokens); |
7968 data.AddSimpleToken(token.kind); | 7965 data.AddSimpleToken(token.kind); |
7969 } | 7966 } |
7970 } | 7967 } |
7971 if (FLAG_compiler_stats) { | 7968 INC_STAT(Isolate::Current(), num_tokens_total, len); |
siva
2015/05/12 17:39:52
Might make sense to cache Isolate::Current() in a
hausner
2015/05/12 21:52:16
Done.
| |
7972 CompilerStats::num_tokens_total += len; | |
7973 } | |
7974 data.AddSimpleToken(Token::kEOS); // End of stream. | 7969 data.AddSimpleToken(Token::kEOS); // End of stream. |
7975 | 7970 |
7976 // Create and setup the token stream object. | 7971 // Create and setup the token stream object. |
7977 const ExternalTypedData& stream = ExternalTypedData::Handle( | 7972 const ExternalTypedData& stream = ExternalTypedData::Handle( |
7978 ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, | 7973 ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, |
7979 data.GetStream(), data.Length(), Heap::kOld)); | 7974 data.GetStream(), data.Length(), Heap::kOld)); |
7980 stream.AddFinalizer(data.GetStream(), DataFinalizer); | 7975 stream.AddFinalizer(data.GetStream(), DataFinalizer); |
7981 const TokenStream& result = TokenStream::Handle(New()); | 7976 const TokenStream& result = TokenStream::Handle(New()); |
7982 result.SetPrivateKey(private_key); | 7977 result.SetPrivateKey(private_key); |
7983 const Array& token_objects = Array::Handle(data.MakeTokenObjectsArray()); | 7978 const Array& token_objects = Array::Handle(data.MakeTokenObjectsArray()); |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8294 | 8289 |
8295 void Script::Tokenize(const String& private_key) const { | 8290 void Script::Tokenize(const String& private_key) const { |
8296 Isolate* isolate = Isolate::Current(); | 8291 Isolate* isolate = Isolate::Current(); |
8297 const TokenStream& tkns = TokenStream::Handle(isolate, tokens()); | 8292 const TokenStream& tkns = TokenStream::Handle(isolate, tokens()); |
8298 if (!tkns.IsNull()) { | 8293 if (!tkns.IsNull()) { |
8299 // Already tokenized. | 8294 // Already tokenized. |
8300 return; | 8295 return; |
8301 } | 8296 } |
8302 // Get the source, scan and allocate the token stream. | 8297 // Get the source, scan and allocate the token stream. |
8303 VMTagScope tagScope(isolate, VMTag::kCompileScannerTagId); | 8298 VMTagScope tagScope(isolate, VMTag::kCompileScannerTagId); |
8304 TimerScope timer(FLAG_compiler_stats, &CompilerStats::scanner_timer); | 8299 TimerScope timer(FLAG_compiler_stats, &CSTAT_TIMER(scanner_timer)); |
8305 const String& src = String::Handle(isolate, Source()); | 8300 const String& src = String::Handle(isolate, Source()); |
8306 Scanner scanner(src, private_key); | 8301 Scanner scanner(src, private_key); |
8307 set_tokens(TokenStream::Handle(isolate, | 8302 set_tokens(TokenStream::Handle(isolate, |
8308 TokenStream::New(scanner.GetStream(), | 8303 TokenStream::New(scanner.GetStream(), |
8309 private_key))); | 8304 private_key))); |
8310 if (FLAG_compiler_stats) { | 8305 INC_STAT(isolate, src_length, src.Length()); |
8311 CompilerStats::src_length += src.Length(); | |
8312 } | |
8313 } | 8306 } |
8314 | 8307 |
8315 | 8308 |
8316 void Script::SetLocationOffset(intptr_t line_offset, | 8309 void Script::SetLocationOffset(intptr_t line_offset, |
8317 intptr_t col_offset) const { | 8310 intptr_t col_offset) const { |
8318 ASSERT(line_offset >= 0); | 8311 ASSERT(line_offset >= 0); |
8319 ASSERT(col_offset >= 0); | 8312 ASSERT(col_offset >= 0); |
8320 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); | 8313 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); |
8321 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); | 8314 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); |
8322 } | 8315 } |
(...skipping 2290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10613 | 10606 |
10614 | 10607 |
10615 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { | 10608 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { |
10616 ASSERT(Object::pc_descriptors_class() != Class::null()); | 10609 ASSERT(Object::pc_descriptors_class() != Class::null()); |
10617 PcDescriptors& result = PcDescriptors::Handle(); | 10610 PcDescriptors& result = PcDescriptors::Handle(); |
10618 { | 10611 { |
10619 uword size = PcDescriptors::InstanceSize(data->length()); | 10612 uword size = PcDescriptors::InstanceSize(data->length()); |
10620 RawObject* raw = Object::Allocate(PcDescriptors::kClassId, | 10613 RawObject* raw = Object::Allocate(PcDescriptors::kClassId, |
10621 size, | 10614 size, |
10622 Heap::kOld); | 10615 Heap::kOld); |
10616 INC_STAT(Isolate::Current(), total_code_size, size); | |
10617 INC_STAT(Isolate::Current(), pc_desc_size, size); | |
siva
2015/05/12 17:39:52
Ditto comment about caching Isolate::Current() ins
hausner
2015/05/12 21:52:16
Done.
| |
10623 NoSafepointScope no_safepoint; | 10618 NoSafepointScope no_safepoint; |
10624 result ^= raw; | 10619 result ^= raw; |
10625 result.SetLength(data->length()); | 10620 result.SetLength(data->length()); |
10626 result.CopyData(data); | 10621 result.CopyData(data); |
10627 } | 10622 } |
10628 return result.raw(); | 10623 return result.raw(); |
10629 } | 10624 } |
10630 | 10625 |
10631 | 10626 |
10632 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { | 10627 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11032 FATAL2("Fatal error in LocalVarDescriptors::New: " | 11027 FATAL2("Fatal error in LocalVarDescriptors::New: " |
11033 "invalid num_variables %" Pd ". Maximum is: %d\n", | 11028 "invalid num_variables %" Pd ". Maximum is: %d\n", |
11034 num_variables, RawLocalVarDescriptors::kMaxIndex); | 11029 num_variables, RawLocalVarDescriptors::kMaxIndex); |
11035 } | 11030 } |
11036 LocalVarDescriptors& result = LocalVarDescriptors::Handle(); | 11031 LocalVarDescriptors& result = LocalVarDescriptors::Handle(); |
11037 { | 11032 { |
11038 uword size = LocalVarDescriptors::InstanceSize(num_variables); | 11033 uword size = LocalVarDescriptors::InstanceSize(num_variables); |
11039 RawObject* raw = Object::Allocate(LocalVarDescriptors::kClassId, | 11034 RawObject* raw = Object::Allocate(LocalVarDescriptors::kClassId, |
11040 size, | 11035 size, |
11041 Heap::kOld); | 11036 Heap::kOld); |
11037 INC_STAT(Isolate::Current(), total_code_size, size); | |
11038 INC_STAT(Isolate::Current(), vardesc_size, size); | |
11042 NoSafepointScope no_safepoint; | 11039 NoSafepointScope no_safepoint; |
11043 result ^= raw; | 11040 result ^= raw; |
11044 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); | 11041 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); |
11045 } | 11042 } |
11046 return result.raw(); | 11043 return result.raw(); |
11047 } | 11044 } |
11048 | 11045 |
11049 | 11046 |
11050 intptr_t LocalVarDescriptors::Length() const { | 11047 intptr_t LocalVarDescriptors::Length() const { |
11051 return raw_ptr()->num_entries_; | 11048 return raw_ptr()->num_entries_; |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12104 | 12101 |
12105 | 12102 |
12106 void Code::set_is_alive(bool value) const { | 12103 void Code::set_is_alive(bool value) const { |
12107 set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); | 12104 set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); |
12108 } | 12105 } |
12109 | 12106 |
12110 | 12107 |
12111 void Code::set_stackmaps(const Array& maps) const { | 12108 void Code::set_stackmaps(const Array& maps) const { |
12112 ASSERT(maps.IsOld()); | 12109 ASSERT(maps.IsOld()); |
12113 StorePointer(&raw_ptr()->stackmaps_, maps.raw()); | 12110 StorePointer(&raw_ptr()->stackmaps_, maps.raw()); |
12111 INC_STAT(Isolate::Current(), | |
12112 total_code_size, | |
12113 maps.IsNull() ? 0 : maps.Length() * sizeof(uword)); | |
12114 } | 12114 } |
12115 | 12115 |
12116 | 12116 |
12117 void Code::set_deopt_info_array(const Array& array) const { | 12117 void Code::set_deopt_info_array(const Array& array) const { |
12118 ASSERT(array.IsOld()); | 12118 ASSERT(array.IsOld()); |
12119 StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); | 12119 StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); |
12120 } | 12120 } |
12121 | 12121 |
12122 | 12122 |
12123 void Code::set_static_calls_target_table(const Array& value) const { | 12123 void Code::set_static_calls_target_table(const Array& value) const { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12322 bool optimized) { | 12322 bool optimized) { |
12323 ASSERT(assembler != NULL); | 12323 ASSERT(assembler != NULL); |
12324 | 12324 |
12325 // Allocate the Code and Instructions objects. Code is allocated first | 12325 // Allocate the Code and Instructions objects. Code is allocated first |
12326 // because a GC during allocation of the code will leave the instruction | 12326 // because a GC during allocation of the code will leave the instruction |
12327 // pages read-only. | 12327 // pages read-only. |
12328 intptr_t pointer_offset_count = assembler->CountPointerOffsets(); | 12328 intptr_t pointer_offset_count = assembler->CountPointerOffsets(); |
12329 Code& code = Code::ZoneHandle(Code::New(pointer_offset_count)); | 12329 Code& code = Code::ZoneHandle(Code::New(pointer_offset_count)); |
12330 Instructions& instrs = | 12330 Instructions& instrs = |
12331 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); | 12331 Instructions::ZoneHandle(Instructions::New(assembler->CodeSize())); |
12332 INC_STAT(Isolate::Current(), total_instr_size, assembler->CodeSize()); | |
12333 INC_STAT(Isolate::Current(), total_code_size, assembler->CodeSize()); | |
12332 | 12334 |
12333 // Copy the instructions into the instruction area and apply all fixups. | 12335 // Copy the instructions into the instruction area and apply all fixups. |
12334 // Embedded pointers are still in handles at this point. | 12336 // Embedded pointers are still in handles at this point. |
12335 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), | 12337 MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()), |
12336 instrs.size()); | 12338 instrs.size()); |
12337 assembler->FinalizeInstructions(region); | 12339 assembler->FinalizeInstructions(region); |
12338 VerifiedMemory::Accept(region.start(), region.size()); | 12340 VerifiedMemory::Accept(region.start(), region.size()); |
12339 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); | 12341 CPU::FlushICache(instrs.EntryPoint(), instrs.size()); |
12340 | 12342 |
12341 code.set_compile_timestamp(OS::GetCurrentTimeMicros()); | 12343 code.set_compile_timestamp(OS::GetCurrentTimeMicros()); |
(...skipping 24 matching lines...) Expand all Loading... | |
12366 // Hook up Code and Instructions objects. | 12368 // Hook up Code and Instructions objects. |
12367 instrs.set_code(code.raw()); | 12369 instrs.set_code(code.raw()); |
12368 code.set_instructions(instrs.raw()); | 12370 code.set_instructions(instrs.raw()); |
12369 code.set_is_alive(true); | 12371 code.set_is_alive(true); |
12370 | 12372 |
12371 // Set object pool in Instructions object. | 12373 // Set object pool in Instructions object. |
12372 const GrowableObjectArray& object_pool = assembler->object_pool_data(); | 12374 const GrowableObjectArray& object_pool = assembler->object_pool_data(); |
12373 if (object_pool.IsNull()) { | 12375 if (object_pool.IsNull()) { |
12374 instrs.set_object_pool(Object::empty_array().raw()); | 12376 instrs.set_object_pool(Object::empty_array().raw()); |
12375 } else { | 12377 } else { |
12378 INC_STAT(Isolate::Current(), | |
12379 total_code_size, object_pool.Length() * sizeof(uintptr_t)); | |
12376 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here | 12380 // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here |
12377 // with Heap::kOld and change the ARM and MIPS assemblers to work with a | 12381 // with Heap::kOld and change the ARM and MIPS assemblers to work with a |
12378 // GrowableObjectArray in new space. | 12382 // GrowableObjectArray in new space. |
12379 instrs.set_object_pool(Array::MakeArray(object_pool)); | 12383 instrs.set_object_pool(Array::MakeArray(object_pool)); |
12380 } | 12384 } |
12381 if (FLAG_write_protect_code) { | 12385 if (FLAG_write_protect_code) { |
12382 uword address = RawObject::ToAddr(instrs.raw()); | 12386 uword address = RawObject::ToAddr(instrs.raw()); |
12383 bool status = VirtualMemory::Protect( | 12387 bool status = VirtualMemory::Protect( |
12384 reinterpret_cast<void*>(address), | 12388 reinterpret_cast<void*>(address), |
12385 instrs.raw()->Size(), | 12389 instrs.raw()->Size(), |
12386 VirtualMemory::kReadExecute); | 12390 VirtualMemory::kReadExecute); |
12387 ASSERT(status); | 12391 ASSERT(status); |
12388 } | 12392 } |
12389 } | 12393 } |
12390 code.set_comments(assembler->GetCodeComments()); | 12394 code.set_comments(assembler->GetCodeComments()); |
12395 INC_STAT(Isolate::Current(), | |
12396 total_code_size, code.comments().comments_.Length()); | |
12391 return code.raw(); | 12397 return code.raw(); |
12392 } | 12398 } |
12393 | 12399 |
12394 | 12400 |
12395 RawCode* Code::FinalizeCode(const Function& function, | 12401 RawCode* Code::FinalizeCode(const Function& function, |
12396 Assembler* assembler, | 12402 Assembler* assembler, |
12397 bool optimized) { | 12403 bool optimized) { |
12398 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 12404 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |
12399 // try to avoid it. | 12405 // try to avoid it. |
12400 if (CodeObservers::AreActive()) { | 12406 if (CodeObservers::AreActive()) { |
(...skipping 8358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
20759 return tag_label.ToCString(); | 20765 return tag_label.ToCString(); |
20760 } | 20766 } |
20761 | 20767 |
20762 | 20768 |
20763 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 20769 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
20764 Instance::PrintJSONImpl(stream, ref); | 20770 Instance::PrintJSONImpl(stream, ref); |
20765 } | 20771 } |
20766 | 20772 |
20767 | 20773 |
20768 } // namespace dart | 20774 } // namespace dart |
OLD | NEW |