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

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

Issue 356923006: Iterate over PcDescriptors only via iterators, not via an index. (preparation for more compression … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
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 10259 matching lines...) Expand 10 before | Expand all | Expand 10 after
10270 size, 10270 size,
10271 Heap::kOld); 10271 Heap::kOld);
10272 NoGCScope no_gc; 10272 NoGCScope no_gc;
10273 result ^= raw; 10273 result ^= raw;
10274 result.SetLength(num_descriptors); 10274 result.SetLength(num_descriptors);
10275 } 10275 }
10276 return result.raw(); 10276 return result.raw();
10277 } 10277 }
10278 10278
10279 10279
10280 const char* PcDescriptors::KindAsStr(intptr_t index) const { 10280 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) {
10281 switch (DescriptorKind(index)) { 10281 switch (kind) {
10282 case PcDescriptors::kDeopt: return "deopt "; 10282 case RawPcDescriptors::kDeopt: return "deopt ";
10283 case PcDescriptors::kIcCall: return "ic-call "; 10283 case RawPcDescriptors::kIcCall: return "ic-call ";
10284 case PcDescriptors::kOptStaticCall: return "opt-call "; 10284 case RawPcDescriptors::kOptStaticCall: return "opt-call ";
10285 case PcDescriptors::kUnoptStaticCall: return "unopt-call "; 10285 case RawPcDescriptors::kUnoptStaticCall: return "unopt-call ";
10286 case PcDescriptors::kClosureCall: return "closure-call "; 10286 case RawPcDescriptors::kClosureCall: return "closure-call ";
10287 case PcDescriptors::kRuntimeCall: return "runtime-call "; 10287 case RawPcDescriptors::kRuntimeCall: return "runtime-call ";
10288 case PcDescriptors::kOsrEntry: return "osr-entry "; 10288 case RawPcDescriptors::kOsrEntry: return "osr-entry ";
10289 case PcDescriptors::kOther: return "other "; 10289 case RawPcDescriptors::kOther: return "other ";
10290 } 10290 }
10291 UNREACHABLE(); 10291 UNREACHABLE();
10292 return ""; 10292 return "";
10293 } 10293 }
10294 10294
10295 10295
10296 void PcDescriptors::PrintHeaderString() { 10296 void PcDescriptors::PrintHeaderString() {
10297 // 4 bits per hex digit + 2 for "0x". 10297 // 4 bits per hex digit + 2 for "0x".
10298 const int addr_width = (kBitsPerWord / 4) + 2; 10298 const int addr_width = (kBitsPerWord / 4) + 2;
10299 // "*" in a printf format specifier tells it to read the field width from 10299 // "*" in a printf format specifier tells it to read the field width from
10300 // the printf argument list. 10300 // the printf argument list.
10301 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", 10301 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n",
10302 addr_width, "pc"); 10302 addr_width, "pc");
10303 } 10303 }
10304 10304
10305 10305
10306 const char* PcDescriptors::ToCString() const { 10306 const char* PcDescriptors::ToCString() const {
10307 if (Length() == 0) { 10307 if (Length() == 0) {
10308 return "No pc descriptors\n"; 10308 return "No pc descriptors\n";
10309 } 10309 }
10310 // 4 bits per hex digit. 10310 // 4 bits per hex digit.
10311 const int addr_width = kBitsPerWord / 4; 10311 const int addr_width = kBitsPerWord / 4;
10312 // "*" in a printf format specifier tells it to read the field width from 10312 // "*" in a printf format specifier tells it to read the field width from
10313 // the printf argument list. 10313 // the printf argument list.
10314 const char* kFormat = 10314 const char* kFormat =
10315 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; 10315 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n";
10316 // First compute the buffer size required. 10316 // First compute the buffer size required.
10317 intptr_t len = 1; // Trailing '\0'. 10317 intptr_t len = 1; // Trailing '\0'.
10318 for (intptr_t i = 0; i < Length(); i++) { 10318 Iterator iter(*this);
10319 while (iter.HasNext()) {
10320 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10319 len += OS::SNPrint(NULL, 0, kFormat, addr_width, 10321 len += OS::SNPrint(NULL, 0, kFormat, addr_width,
10320 PC(i), 10322 rec.pc,
10321 KindAsStr(i), 10323 KindAsStr(rec.kind()),
10322 DeoptId(i), 10324 rec.deopt_id,
10323 TokenPos(i), 10325 rec.token_pos,
10324 TryIndex(i)); 10326 rec.try_index);
10325 } 10327 }
10326 // Allocate the buffer. 10328 // Allocate the buffer.
10327 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); 10329 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len);
10328 // Layout the fields in the buffer. 10330 // Layout the fields in the buffer.
10329 intptr_t index = 0; 10331 intptr_t index = 0;
10330 for (intptr_t i = 0; i < Length(); i++) { 10332 Iterator iter2(*this);
10333 while (iter2.HasNext()) {
10334 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next();
10331 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, 10335 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width,
10332 PC(i), 10336 rec.pc,
10333 KindAsStr(i), 10337 KindAsStr(rec.kind()),
10334 DeoptId(i), 10338 rec.deopt_id,
10335 TokenPos(i), 10339 rec.token_pos,
10336 TryIndex(i)); 10340 rec.try_index);
10337 } 10341 }
10338 return buffer; 10342 return buffer;
10339 } 10343 }
10340 10344
10341 10345
10342 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { 10346 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const {
10343 jsobj->AddProperty("type", JSONType(false)); 10347 jsobj->AddProperty("type", JSONType(false));
10344 // TODO(johnmccutchan): Generate a valid ID. 10348 // TODO(johnmccutchan): Generate a valid ID.
10345 // PcDescriptors hang off a Code object but do not have a back reference to 10349 // PcDescriptors hang off a Code object but do not have a back reference to
10346 // generate an ID. Currently we only print PcDescriptors inline with a Code. 10350 // generate an ID. Currently we only print PcDescriptors inline with a Code.
10347 jsobj->AddProperty("id", ""); 10351 jsobj->AddProperty("id", "");
10348 JSONArray members(jsobj, "members"); 10352 JSONArray members(jsobj, "members");
10349 for (intptr_t i = 0; i < Length(); i++) { 10353 Iterator iter(*this);
10354 while (iter.HasNext()) {
10355 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10350 JSONObject descriptor(&members); 10356 JSONObject descriptor(&members);
10351 descriptor.AddPropertyF("pc", "%" Px "", PC(i)); 10357 descriptor.AddPropertyF("pc", "%" Px "", rec.pc);
10352 descriptor.AddProperty("kind", KindAsStr(i)); 10358 descriptor.AddProperty("kind", KindAsStr(rec.kind()));
10353 descriptor.AddProperty("deoptId", DeoptId(i)); 10359 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id));
10354 descriptor.AddProperty("tokenPos", TokenPos(i)); 10360 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos));
10355 descriptor.AddProperty("tryIndex", TryIndex(i)); 10361 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index));
10356 } 10362 }
10357 } 10363 }
10358 10364
10359 10365
10360 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { 10366 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const {
10361 JSONObject jsobj(stream); 10367 JSONObject jsobj(stream);
10362 PrintToJSONObject(&jsobj); 10368 PrintToJSONObject(&jsobj);
10363 } 10369 }
10364 10370
10365 10371
10366 // Verify assumptions (in debug mode only). 10372 // Verify assumptions (in debug mode only).
10367 // - No two deopt descriptors have the same deoptimization id. 10373 // - No two deopt descriptors have the same deoptimization id.
10368 // - No two ic-call descriptors have the same deoptimization id (type feedback). 10374 // - No two ic-call descriptors have the same deoptimization id (type feedback).
10369 // A function without unique ids is marked as non-optimizable (e.g., because of 10375 // A function without unique ids is marked as non-optimizable (e.g., because of
10370 // finally blocks). 10376 // finally blocks).
10371 void PcDescriptors::Verify(const Function& function) const { 10377 void PcDescriptors::Verify(const Function& function) const {
10372 #if defined(DEBUG) 10378 #if defined(DEBUG)
10373 // TODO(srdjan): Implement a more efficient way to check, currently drop 10379 // TODO(srdjan): Implement a more efficient way to check, currently drop
10374 // the check for too large number of descriptors. 10380 // the check for too large number of descriptors.
10375 if (Length() > 3000) { 10381 if (Length() > 3000) {
10376 if (FLAG_trace_compiler) { 10382 if (FLAG_trace_compiler) {
10377 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); 10383 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length());
10378 } 10384 }
10379 return; 10385 return;
10380 } 10386 }
10381 // Only check ids for unoptimized code that is optimizable. 10387 // Only check ids for unoptimized code that is optimizable.
10382 if (!function.IsOptimizable()) return; 10388 if (!function.IsOptimizable()) {
10383 for (intptr_t i = 0; i < Length(); i++) { 10389 return;
10384 PcDescriptors::Kind kind = DescriptorKind(i); 10390 }
10391 Iterator iter(*this);
10392 while (iter.HasNext()) {
10393 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10394 RawPcDescriptors::Kind kind = rec.kind();
10385 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. 10395 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
10386 intptr_t deopt_id = Isolate::kNoDeoptId; 10396 intptr_t deopt_id = Isolate::kNoDeoptId;
10387 if ((DescriptorKind(i) != PcDescriptors::kDeopt) || 10397 if ((kind != RawPcDescriptors::kDeopt) ||
10388 (DescriptorKind(i) != PcDescriptors::kIcCall)) { 10398 (kind != RawPcDescriptors::kIcCall)) {
10389 continue; 10399 continue;
10390 } 10400 }
10391 10401
10392 deopt_id = DeoptId(i); 10402 deopt_id = rec.deopt_id;
10393 if (Isolate::IsDeoptAfter(deopt_id)) { 10403 if (Isolate::IsDeoptAfter(deopt_id)) {
10394 // TODO(vegorov): some instructions contain multiple calls and have 10404 // TODO(vegorov): some instructions contain multiple calls and have
10395 // multiple "after" targets recorded. Right now it is benign but might 10405 // multiple "after" targets recorded. Right now it is benign but might
10396 // lead to issues in the future. Fix that and enable verification. 10406 // lead to issues in the future. Fix that and enable verification.
10397 continue; 10407 continue;
10398 } 10408 }
10399 10409
10400 for (intptr_t k = i + 1; k < Length(); k++) { 10410 Iterator nested(iter);
10401 if (kind == DescriptorKind(k)) { 10411 while (iter.HasNext()) {
10412 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next();
10413 if (kind == nested_rec.kind()) {
10402 if (deopt_id != Isolate::kNoDeoptId) { 10414 if (deopt_id != Isolate::kNoDeoptId) {
10403 ASSERT(DeoptId(k) != deopt_id); 10415 ASSERT(nested_rec.deopt_id != deopt_id);
10404 } 10416 }
10405 } 10417 }
10406 } 10418 }
10407 } 10419 }
10408 #endif // DEBUG 10420 #endif // DEBUG
10409 } 10421 }
10410 10422
10411 10423
10412 uword PcDescriptors::GetPcForKind(Kind kind) const { 10424 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const {
10413 for (intptr_t i = 0; i < Length(); i++) { 10425 Iterator iter(*this);
10414 if (DescriptorKind(i) == kind) { 10426 while (iter.HasNext()) {
10415 return PC(i); 10427 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10428 if (rec.kind() == kind) {
10429 return rec.pc;
10416 } 10430 }
10417 } 10431 }
10418 return 0; 10432 return 0;
10419 } 10433 }
10420 10434
10421 10435
10422 bool Stackmap::GetBit(intptr_t bit_index) const { 10436 bool Stackmap::GetBit(intptr_t bit_index) const {
10423 ASSERT(InRange(bit_index)); 10437 ASSERT(InRange(bit_index));
10424 int byte_index = bit_index >> kBitsPerByteLog2; 10438 int byte_index = bit_index >> kBitsPerByteLog2;
10425 int bit_remainder = bit_index & (kBitsPerByte - 1); 10439 int bit_remainder = bit_index & (kBitsPerByte - 1);
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
11902 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && 11916 if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
11903 (code.EntryPoint() == pc)) { 11917 (code.EntryPoint() == pc)) {
11904 // Found code in VM isolate. 11918 // Found code in VM isolate.
11905 return code.raw(); 11919 return code.raw();
11906 } 11920 }
11907 return Code::null(); 11921 return Code::null();
11908 } 11922 }
11909 11923
11910 11924
11911 intptr_t Code::GetTokenIndexOfPC(uword pc) const { 11925 intptr_t Code::GetTokenIndexOfPC(uword pc) const {
11912 intptr_t token_pos = -1;
11913 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11926 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11914 for (intptr_t i = 0; i < descriptors.Length(); i++) { 11927 PcDescriptors::Iterator iter(descriptors);
11915 if (descriptors.PC(i) == pc) { 11928 while (iter.HasNext()) {
11916 token_pos = descriptors.TokenPos(i); 11929 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11917 break; 11930 if (rec.pc == pc) {
11931 return rec.token_pos;
11918 } 11932 }
11919 } 11933 }
11920 return token_pos; 11934 return -1;
11921 } 11935 }
11922 11936
11923 11937
11924 uword Code::GetPcForDeoptId(intptr_t deopt_id, PcDescriptors::Kind kind) const { 11938 uword Code::GetPcForDeoptId(intptr_t deopt_id,
11939 RawPcDescriptors::Kind kind) const {
11925 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11940 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11926 for (intptr_t i = 0; i < descriptors.Length(); i++) { 11941 PcDescriptors::Iterator iter(descriptors);
11927 if ((descriptors.DeoptId(i) == deopt_id) && 11942 while (iter.HasNext()) {
11928 (descriptors.DescriptorKind(i) == kind)) { 11943 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11929 uword pc = descriptors.PC(i); 11944 if ((rec.deopt_id == deopt_id) && (rec.kind() == kind)) {
11945 uword pc = rec.pc;
11930 ASSERT(ContainsInstructionAt(pc)); 11946 ASSERT(ContainsInstructionAt(pc));
11931 return pc; 11947 return pc;
11932 } 11948 }
11933 } 11949 }
11934 return 0; 11950 return 0;
11935 } 11951 }
11936 11952
11937 11953
11938 intptr_t Code::GetDeoptIdForOsr(uword pc) const { 11954 intptr_t Code::GetDeoptIdForOsr(uword pc) const {
11939 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11955 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11940 for (intptr_t i = 0; i < descriptors.Length(); ++i) { 11956 PcDescriptors::Iterator iter(descriptors);
11941 if ((descriptors.PC(i) == pc) && 11957 while (iter.HasNext()) {
11942 (descriptors.DescriptorKind(i) == PcDescriptors::kOsrEntry)) { 11958 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11943 return descriptors.DeoptId(i); 11959 if ((rec.pc == pc) && (rec.kind() == RawPcDescriptors::kOsrEntry)) {
11960 return rec.deopt_id;
11944 } 11961 }
11945 } 11962 }
11946 return Isolate::kNoDeoptId; 11963 return Isolate::kNoDeoptId;
11947 } 11964 }
11948 11965
11949 11966
11950 const char* Code::ToCString() const { 11967 const char* Code::ToCString() const {
11951 const char* kFormat = "Code entry:%p"; 11968 const char* kFormat = "Code entry:%p";
11952 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; 11969 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1;
11953 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 11970 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
(...skipping 7136 matching lines...) Expand 10 before | Expand all | Expand 10 after
19090 return tag_label.ToCString(); 19107 return tag_label.ToCString();
19091 } 19108 }
19092 19109
19093 19110
19094 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19111 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19095 Instance::PrintJSONImpl(stream, ref); 19112 Instance::PrintJSONImpl(stream, ref);
19096 } 19113 }
19097 19114
19098 19115
19099 } // namespace dart 19116 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698