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

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 10177 matching lines...) Expand 10 before | Expand all | Expand 10 after
10188 size, 10188 size,
10189 Heap::kOld); 10189 Heap::kOld);
10190 NoGCScope no_gc; 10190 NoGCScope no_gc;
10191 result ^= raw; 10191 result ^= raw;
10192 result.SetLength(num_descriptors); 10192 result.SetLength(num_descriptors);
10193 } 10193 }
10194 return result.raw(); 10194 return result.raw();
10195 } 10195 }
10196 10196
10197 10197
10198 const char* PcDescriptors::KindAsStr(intptr_t index) const { 10198 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) {
10199 switch (DescriptorKind(index)) { 10199 switch (kind) {
10200 case PcDescriptors::kDeopt: return "deopt "; 10200 case RawPcDescriptors::kDeopt: return "deopt ";
10201 case PcDescriptors::kIcCall: return "ic-call "; 10201 case RawPcDescriptors::kIcCall: return "ic-call ";
10202 case PcDescriptors::kOptStaticCall: return "opt-call "; 10202 case RawPcDescriptors::kOptStaticCall: return "opt-call ";
10203 case PcDescriptors::kUnoptStaticCall: return "unopt-call "; 10203 case RawPcDescriptors::kUnoptStaticCall: return "unopt-call ";
10204 case PcDescriptors::kClosureCall: return "closure-call "; 10204 case RawPcDescriptors::kClosureCall: return "closure-call ";
10205 case PcDescriptors::kRuntimeCall: return "runtime-call "; 10205 case RawPcDescriptors::kRuntimeCall: return "runtime-call ";
10206 case PcDescriptors::kOsrEntry: return "osr-entry "; 10206 case RawPcDescriptors::kOsrEntry: return "osr-entry ";
10207 case PcDescriptors::kOther: return "other "; 10207 case RawPcDescriptors::kOther: return "other ";
10208 } 10208 }
10209 UNREACHABLE(); 10209 UNREACHABLE();
10210 return ""; 10210 return "";
10211 } 10211 }
10212 10212
10213 10213
10214 void PcDescriptors::PrintHeaderString() { 10214 void PcDescriptors::PrintHeaderString() {
10215 // 4 bits per hex digit + 2 for "0x". 10215 // 4 bits per hex digit + 2 for "0x".
10216 const int addr_width = (kBitsPerWord / 4) + 2; 10216 const int addr_width = (kBitsPerWord / 4) + 2;
10217 // "*" in a printf format specifier tells it to read the field width from 10217 // "*" in a printf format specifier tells it to read the field width from
10218 // the printf argument list. 10218 // the printf argument list.
10219 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", 10219 OS::Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n",
10220 addr_width, "pc"); 10220 addr_width, "pc");
10221 } 10221 }
10222 10222
10223 10223
10224 const char* PcDescriptors::ToCString() const { 10224 const char* PcDescriptors::ToCString() const {
10225 if (Length() == 0) { 10225 if (Length() == 0) {
10226 return "No pc descriptors\n"; 10226 return "No pc descriptors\n";
10227 } 10227 }
10228 // 4 bits per hex digit. 10228 // 4 bits per hex digit.
10229 const int addr_width = kBitsPerWord / 4; 10229 const int addr_width = kBitsPerWord / 4;
10230 // "*" in a printf format specifier tells it to read the field width from 10230 // "*" in a printf format specifier tells it to read the field width from
10231 // the printf argument list. 10231 // the printf argument list.
10232 const char* kFormat = 10232 const char* kFormat =
10233 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"; 10233 "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n";
10234 // First compute the buffer size required. 10234 // First compute the buffer size required.
10235 intptr_t len = 1; // Trailing '\0'. 10235 intptr_t len = 1; // Trailing '\0'.
10236 for (intptr_t i = 0; i < Length(); i++) { 10236 Iterator iter(*this);
10237 while (iter.HasNext()) {
10238 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10237 len += OS::SNPrint(NULL, 0, kFormat, addr_width, 10239 len += OS::SNPrint(NULL, 0, kFormat, addr_width,
10238 PC(i), 10240 rec.pc,
10239 KindAsStr(i), 10241 KindAsStr(rec.kind()),
10240 DeoptId(i), 10242 rec.deopt_id,
10241 TokenPos(i), 10243 rec.token_pos,
10242 TryIndex(i)); 10244 rec.try_index);
10243 } 10245 }
10244 // Allocate the buffer. 10246 // Allocate the buffer.
10245 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); 10247 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len);
10246 // Layout the fields in the buffer. 10248 // Layout the fields in the buffer.
10247 intptr_t index = 0; 10249 intptr_t index = 0;
10248 for (intptr_t i = 0; i < Length(); i++) { 10250 Iterator iter2(*this);
10251 while (iter2.HasNext()) {
10252 const RawPcDescriptors::PcDescriptorRec& rec = iter2.Next();
10249 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width, 10253 index += OS::SNPrint((buffer + index), (len - index), kFormat, addr_width,
10250 PC(i), 10254 rec.pc,
10251 KindAsStr(i), 10255 KindAsStr(rec.kind()),
10252 DeoptId(i), 10256 rec.deopt_id,
10253 TokenPos(i), 10257 rec.token_pos,
10254 TryIndex(i)); 10258 rec.try_index);
10255 } 10259 }
10256 return buffer; 10260 return buffer;
10257 } 10261 }
10258 10262
10259 10263
10260 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const { 10264 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj) const {
10261 jsobj->AddProperty("type", JSONType(false)); 10265 jsobj->AddProperty("type", JSONType(false));
10262 // TODO(johnmccutchan): Generate a valid ID. 10266 // TODO(johnmccutchan): Generate a valid ID.
10263 // PcDescriptors hang off a Code object but do not have a back reference to 10267 // PcDescriptors hang off a Code object but do not have a back reference to
10264 // generate an ID. Currently we only print PcDescriptors inline with a Code. 10268 // generate an ID. Currently we only print PcDescriptors inline with a Code.
10265 jsobj->AddProperty("id", ""); 10269 jsobj->AddProperty("id", "");
10266 JSONArray members(jsobj, "members"); 10270 JSONArray members(jsobj, "members");
10267 for (intptr_t i = 0; i < Length(); i++) { 10271 Iterator iter(*this);
10272 while (iter.HasNext()) {
10273 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10268 JSONObject descriptor(&members); 10274 JSONObject descriptor(&members);
10269 descriptor.AddPropertyF("pc", "%" Px "", PC(i)); 10275 descriptor.AddPropertyF("pc", "%" Px "", rec.pc);
10270 descriptor.AddProperty("kind", KindAsStr(i)); 10276 descriptor.AddProperty("kind", KindAsStr(rec.kind()));
10271 descriptor.AddProperty("deoptId", DeoptId(i)); 10277 descriptor.AddProperty("deoptId", static_cast<intptr_t>(rec.deopt_id));
10272 descriptor.AddProperty("tokenPos", TokenPos(i)); 10278 descriptor.AddProperty("tokenPos", static_cast<intptr_t>(rec.token_pos));
10273 descriptor.AddProperty("tryIndex", TryIndex(i)); 10279 descriptor.AddProperty("tryIndex", static_cast<intptr_t>(rec.try_index));
10274 } 10280 }
10275 } 10281 }
10276 10282
10277 10283
10278 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { 10284 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const {
10279 JSONObject jsobj(stream); 10285 JSONObject jsobj(stream);
10280 PrintToJSONObject(&jsobj); 10286 PrintToJSONObject(&jsobj);
10281 } 10287 }
10282 10288
10283 10289
10284 // Verify assumptions (in debug mode only). 10290 // Verify assumptions (in debug mode only).
10285 // - No two deopt descriptors have the same deoptimization id. 10291 // - No two deopt descriptors have the same deoptimization id.
10286 // - No two ic-call descriptors have the same deoptimization id (type feedback). 10292 // - No two ic-call descriptors have the same deoptimization id (type feedback).
10287 // A function without unique ids is marked as non-optimizable (e.g., because of 10293 // A function without unique ids is marked as non-optimizable (e.g., because of
10288 // finally blocks). 10294 // finally blocks).
10289 void PcDescriptors::Verify(const Function& function) const { 10295 void PcDescriptors::Verify(const Function& function) const {
10290 #if defined(DEBUG) 10296 #if defined(DEBUG)
10291 // TODO(srdjan): Implement a more efficient way to check, currently drop 10297 // TODO(srdjan): Implement a more efficient way to check, currently drop
10292 // the check for too large number of descriptors. 10298 // the check for too large number of descriptors.
10293 if (Length() > 3000) { 10299 if (Length() > 3000) {
10294 if (FLAG_trace_compiler) { 10300 if (FLAG_trace_compiler) {
10295 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length()); 10301 OS::Print("Not checking pc decriptors, length %" Pd "\n", Length());
10296 } 10302 }
10297 return; 10303 return;
10298 } 10304 }
10299 // Only check ids for unoptimized code that is optimizable. 10305 // Only check ids for unoptimized code that is optimizable.
10300 if (!function.IsOptimizable()) return; 10306 if (!function.IsOptimizable()) {
10301 for (intptr_t i = 0; i < Length(); i++) { 10307 return;
10302 PcDescriptors::Kind kind = DescriptorKind(i); 10308 }
10309 Iterator iter(*this);
10310 while (iter.HasNext()) {
10311 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10312 RawPcDescriptors::Kind kind = rec.kind();
10303 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. 10313 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
10304 intptr_t deopt_id = Isolate::kNoDeoptId; 10314 intptr_t deopt_id = Isolate::kNoDeoptId;
10305 if ((DescriptorKind(i) != PcDescriptors::kDeopt) || 10315 if ((kind != RawPcDescriptors::kDeopt) ||
10306 (DescriptorKind(i) != PcDescriptors::kIcCall)) { 10316 (kind != RawPcDescriptors::kIcCall)) {
10307 continue; 10317 continue;
10308 } 10318 }
10309 10319
10310 deopt_id = DeoptId(i); 10320 deopt_id = rec.deopt_id;
10311 if (Isolate::IsDeoptAfter(deopt_id)) { 10321 if (Isolate::IsDeoptAfter(deopt_id)) {
10312 // TODO(vegorov): some instructions contain multiple calls and have 10322 // TODO(vegorov): some instructions contain multiple calls and have
10313 // multiple "after" targets recorded. Right now it is benign but might 10323 // multiple "after" targets recorded. Right now it is benign but might
10314 // lead to issues in the future. Fix that and enable verification. 10324 // lead to issues in the future. Fix that and enable verification.
10315 continue; 10325 continue;
10316 } 10326 }
10317 10327
10318 for (intptr_t k = i + 1; k < Length(); k++) { 10328 Iterator nested(iter);
10319 if (kind == DescriptorKind(k)) { 10329 while (iter.HasNext()) {
10330 const RawPcDescriptors::PcDescriptorRec& nested_rec = nested.Next();
10331 if (kind == nested_rec.kind()) {
10320 if (deopt_id != Isolate::kNoDeoptId) { 10332 if (deopt_id != Isolate::kNoDeoptId) {
10321 ASSERT(DeoptId(k) != deopt_id); 10333 ASSERT(nested_rec.deopt_id != deopt_id);
10322 } 10334 }
10323 } 10335 }
10324 } 10336 }
10325 } 10337 }
10326 #endif // DEBUG 10338 #endif // DEBUG
10327 } 10339 }
10328 10340
10329 10341
10330 uword PcDescriptors::GetPcForKind(Kind kind) const { 10342 uword PcDescriptors::GetPcForKind(RawPcDescriptors::Kind kind) const {
10331 for (intptr_t i = 0; i < Length(); i++) { 10343 Iterator iter(*this);
10332 if (DescriptorKind(i) == kind) { 10344 while (iter.HasNext()) {
10333 return PC(i); 10345 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
10346 if (rec.kind() == kind) {
10347 return rec.pc;
10334 } 10348 }
10335 } 10349 }
10336 return 0; 10350 return 0;
10337 } 10351 }
10338 10352
10339 10353
10340 bool Stackmap::GetBit(intptr_t bit_index) const { 10354 bool Stackmap::GetBit(intptr_t bit_index) const {
10341 ASSERT(InRange(bit_index)); 10355 ASSERT(InRange(bit_index));
10342 int byte_index = bit_index >> kBitsPerByteLog2; 10356 int byte_index = bit_index >> kBitsPerByteLog2;
10343 int bit_remainder = bit_index & (kBitsPerByte - 1); 10357 int bit_remainder = bit_index & (kBitsPerByte - 1);
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
11820 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && 11834 if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
11821 (code.EntryPoint() == pc)) { 11835 (code.EntryPoint() == pc)) {
11822 // Found code in VM isolate. 11836 // Found code in VM isolate.
11823 return code.raw(); 11837 return code.raw();
11824 } 11838 }
11825 return Code::null(); 11839 return Code::null();
11826 } 11840 }
11827 11841
11828 11842
11829 intptr_t Code::GetTokenIndexOfPC(uword pc) const { 11843 intptr_t Code::GetTokenIndexOfPC(uword pc) const {
11830 intptr_t token_pos = -1;
11831 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11844 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11832 for (intptr_t i = 0; i < descriptors.Length(); i++) { 11845 PcDescriptors::Iterator iter(descriptors);
11833 if (descriptors.PC(i) == pc) { 11846 while (iter.HasNext()) {
11834 token_pos = descriptors.TokenPos(i); 11847 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11835 break; 11848 if (rec.pc == pc) {
11849 return rec.token_pos;
11836 } 11850 }
11837 } 11851 }
11838 return token_pos; 11852 return -1;
11839 } 11853 }
11840 11854
11841 11855
11842 uword Code::GetPcForDeoptId(intptr_t deopt_id, PcDescriptors::Kind kind) const { 11856 uword Code::GetPcForDeoptId(intptr_t deopt_id,
11857 RawPcDescriptors::Kind kind) const {
11843 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11858 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11844 for (intptr_t i = 0; i < descriptors.Length(); i++) { 11859 PcDescriptors::Iterator iter(descriptors);
11845 if ((descriptors.DeoptId(i) == deopt_id) && 11860 while (iter.HasNext()) {
11846 (descriptors.DescriptorKind(i) == kind)) { 11861 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11847 uword pc = descriptors.PC(i); 11862 if ((rec.deopt_id == deopt_id) && (rec.kind() == kind)) {
11863 uword pc = rec.pc;
11848 ASSERT(ContainsInstructionAt(pc)); 11864 ASSERT(ContainsInstructionAt(pc));
11849 return pc; 11865 return pc;
11850 } 11866 }
11851 } 11867 }
11852 return 0; 11868 return 0;
11853 } 11869 }
11854 11870
11855 11871
11856 intptr_t Code::GetDeoptIdForOsr(uword pc) const { 11872 intptr_t Code::GetDeoptIdForOsr(uword pc) const {
11857 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); 11873 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
11858 for (intptr_t i = 0; i < descriptors.Length(); ++i) { 11874 PcDescriptors::Iterator iter(descriptors);
11859 if ((descriptors.PC(i) == pc) && 11875 while (iter.HasNext()) {
11860 (descriptors.DescriptorKind(i) == PcDescriptors::kOsrEntry)) { 11876 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
11861 return descriptors.DeoptId(i); 11877 if ((rec.pc == pc) && (rec.kind() == RawPcDescriptors::kOsrEntry)) {
11878 return rec.deopt_id;
11862 } 11879 }
11863 } 11880 }
11864 return Isolate::kNoDeoptId; 11881 return Isolate::kNoDeoptId;
11865 } 11882 }
11866 11883
11867 11884
11868 const char* Code::ToCString() const { 11885 const char* Code::ToCString() const {
11869 const char* kFormat = "Code entry:%p"; 11886 const char* kFormat = "Code entry:%p";
11870 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; 11887 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1;
11871 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 11888 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
(...skipping 7165 matching lines...) Expand 10 before | Expand all | Expand 10 after
19037 return tag_label.ToCString(); 19054 return tag_label.ToCString();
19038 } 19055 }
19039 19056
19040 19057
19041 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19042 Instance::PrintJSONImpl(stream, ref); 19059 Instance::PrintJSONImpl(stream, ref);
19043 } 19060 }
19044 19061
19045 19062
19046 } // namespace dart 19063 } // namespace dart
OLDNEW
« runtime/vm/debugger.cc ('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