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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 6521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6532 PcDescriptors::Kind PcDescriptors::DescriptorKind(intptr_t index) const { | 6532 PcDescriptors::Kind PcDescriptors::DescriptorKind(intptr_t index) const { |
6533 return static_cast<PcDescriptors::Kind>(*(EntryAddr(index, kKindEntry))); | 6533 return static_cast<PcDescriptors::Kind>(*(EntryAddr(index, kKindEntry))); |
6534 } | 6534 } |
6535 | 6535 |
6536 | 6536 |
6537 void PcDescriptors::SetKind(intptr_t index, PcDescriptors::Kind value) const { | 6537 void PcDescriptors::SetKind(intptr_t index, PcDescriptors::Kind value) const { |
6538 *(EntryAddr(index, kKindEntry)) = value; | 6538 *(EntryAddr(index, kKindEntry)) = value; |
6539 } | 6539 } |
6540 | 6540 |
6541 | 6541 |
6542 intptr_t PcDescriptors::NodeId(intptr_t index) const { | 6542 intptr_t PcDescriptors::DeoptId(intptr_t index) const { |
6543 return Smi::Value(*SmiAddr(index, kNodeIdEntry)); | 6543 return Smi::Value(*SmiAddr(index, kDeoptIdEntry)); |
6544 } | 6544 } |
6545 | 6545 |
6546 | 6546 |
6547 void PcDescriptors::SetNodeId(intptr_t index, intptr_t value) const { | 6547 void PcDescriptors::SetDeoptId(intptr_t index, intptr_t value) const { |
6548 *SmiAddr(index, kNodeIdEntry) = Smi::New(value); | 6548 *SmiAddr(index, kDeoptIdEntry) = Smi::New(value); |
6549 } | 6549 } |
6550 | 6550 |
6551 | 6551 |
6552 intptr_t PcDescriptors::TokenIndex(intptr_t index) const { | 6552 intptr_t PcDescriptors::TokenPos(intptr_t index) const { |
6553 return Smi::Value(*SmiAddr(index, kTokenIndexEntry)); | 6553 return Smi::Value(*SmiAddr(index, kTokenPosEntry)); |
6554 } | 6554 } |
6555 | 6555 |
6556 | 6556 |
6557 void PcDescriptors::SetTokenIndex(intptr_t index, intptr_t value) const { | 6557 void PcDescriptors::SetTokenPos(intptr_t index, intptr_t value) const { |
6558 *SmiAddr(index, kTokenIndexEntry) = Smi::New(value); | 6558 *SmiAddr(index, kTokenPosEntry) = Smi::New(value); |
6559 } | 6559 } |
6560 | 6560 |
6561 | 6561 |
6562 intptr_t PcDescriptors::TryIndex(intptr_t index) const { | 6562 intptr_t PcDescriptors::TryIndex(intptr_t index) const { |
6563 ASSERT(DescriptorKind(index) != kDeoptIndex); | 6563 ASSERT(DescriptorKind(index) != kDeoptIndex); |
6564 return *(EntryAddr(index, kTryIndexEntry)); | 6564 return *(EntryAddr(index, kTryIndexEntry)); |
6565 } | 6565 } |
6566 | 6566 |
6567 | 6567 |
6568 intptr_t PcDescriptors::DeoptIndex(intptr_t index) const { | 6568 intptr_t PcDescriptors::DeoptIndex(intptr_t index) const { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6616 if (Length() == 0) { | 6616 if (Length() == 0) { |
6617 return "No pc descriptors\n"; | 6617 return "No pc descriptors\n"; |
6618 } | 6618 } |
6619 const char* kFormat = "0x%x\t%s\t%ld\t%ld\t%ld\n"; | 6619 const char* kFormat = "0x%x\t%s\t%ld\t%ld\t%ld\n"; |
6620 // First compute the buffer size required. | 6620 // First compute the buffer size required. |
6621 intptr_t len = 0; | 6621 intptr_t len = 0; |
6622 for (intptr_t i = 0; i < Length(); i++) { | 6622 for (intptr_t i = 0; i < Length(); i++) { |
6623 const intptr_t multi_purpose_index = DescriptorKind(i) == kDeoptIndex ? | 6623 const intptr_t multi_purpose_index = DescriptorKind(i) == kDeoptIndex ? |
6624 DeoptIndex(i) : TryIndex(i); | 6624 DeoptIndex(i) : TryIndex(i); |
6625 len += OS::SNPrint(NULL, 0, kFormat, | 6625 len += OS::SNPrint(NULL, 0, kFormat, |
6626 PC(i), KindAsStr(i), NodeId(i), TokenIndex(i), multi_purpose_index); | 6626 PC(i), KindAsStr(i), DeoptId(i), TokenPos(i), multi_purpose_index); |
6627 } | 6627 } |
6628 // Allocate the buffer. | 6628 // Allocate the buffer. |
6629 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 6629 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
6630 // Layout the fields in the buffer. | 6630 // Layout the fields in the buffer. |
6631 intptr_t index = 0; | 6631 intptr_t index = 0; |
6632 for (intptr_t i = 0; i < Length(); i++) { | 6632 for (intptr_t i = 0; i < Length(); i++) { |
6633 const intptr_t multi_purpose_index = DescriptorKind(i) == kDeoptIndex ? | 6633 const intptr_t multi_purpose_index = DescriptorKind(i) == kDeoptIndex ? |
6634 DeoptIndex(i) : TryIndex(i); | 6634 DeoptIndex(i) : TryIndex(i); |
6635 index += OS::SNPrint((buffer + index), (len - index), kFormat, | 6635 index += OS::SNPrint((buffer + index), (len - index), kFormat, |
6636 PC(i), KindAsStr(i), NodeId(i), TokenIndex(i), multi_purpose_index); | 6636 PC(i), KindAsStr(i), DeoptId(i), TokenPos(i), multi_purpose_index); |
6637 } | 6637 } |
6638 return buffer; | 6638 return buffer; |
6639 } | 6639 } |
6640 | 6640 |
6641 | 6641 |
6642 // Verify assumptions (in debug mode only). | 6642 // Verify assumptions (in debug mode only). |
6643 // - No two deopt descriptors have the same node id (deoptimization). | 6643 // - No two deopt descriptors have the same node id (deoptimization). |
6644 // - No two ic-call descriptors have the same node id (type feedback). | 6644 // - No two ic-call descriptors have the same node id (type feedback). |
6645 // - No two descriptors of same kind have the same PC. | 6645 // - No two descriptors of same kind have the same PC. |
6646 // A function without unique ids is marked as non-optimizable (e.g., because of | 6646 // A function without unique ids is marked as non-optimizable (e.g., because of |
6647 // finally blocks). | 6647 // finally blocks). |
6648 void PcDescriptors::Verify(bool check_ids) const { | 6648 void PcDescriptors::Verify(bool check_ids) const { |
6649 #if defined(DEBUG) | 6649 #if defined(DEBUG) |
6650 // TODO(srdjan): Implement a more efficient way to check, currently drop | 6650 // TODO(srdjan): Implement a more efficient way to check, currently drop |
6651 // the check for too large number of descriptors. | 6651 // the check for too large number of descriptors. |
6652 if (Length() > 3000) { | 6652 if (Length() > 3000) { |
6653 if (FLAG_trace_compiler) { | 6653 if (FLAG_trace_compiler) { |
6654 OS::Print("Not checking pc decriptors, length %d\n", Length()); | 6654 OS::Print("Not checking pc decriptors, length %d\n", Length()); |
6655 } | 6655 } |
6656 return; | 6656 return; |
6657 } | 6657 } |
6658 for (intptr_t i = 0; i < Length(); i++) { | 6658 for (intptr_t i = 0; i < Length(); i++) { |
6659 uword pc = PC(i); | 6659 uword pc = PC(i); |
6660 PcDescriptors::Kind kind = DescriptorKind(i); | 6660 PcDescriptors::Kind kind = DescriptorKind(i); |
6661 // 'node_id' is set for kDeopt and kIcCall and must be unique for one kind. | 6661 // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. |
6662 intptr_t node_id = AstNode::kNoId; | 6662 intptr_t deopt_id = Isolate::kNoDeoptId; |
6663 if (check_ids) { | 6663 if (check_ids) { |
6664 if ((DescriptorKind(i) == PcDescriptors::kDeopt) || | 6664 if ((DescriptorKind(i) == PcDescriptors::kDeopt) || |
6665 (DescriptorKind(i) == PcDescriptors::kIcCall)) { | 6665 (DescriptorKind(i) == PcDescriptors::kIcCall)) { |
6666 node_id = NodeId(i); | 6666 deopt_id = DeoptId(i); |
6667 } | 6667 } |
6668 } | 6668 } |
6669 for (intptr_t k = i + 1; k < Length(); k++) { | 6669 for (intptr_t k = i + 1; k < Length(); k++) { |
6670 if (kind == DescriptorKind(k)) { | 6670 if (kind == DescriptorKind(k)) { |
6671 if (node_id != AstNode::kNoId) { | 6671 if (deopt_id != Isolate::kNoDeoptId) { |
6672 ASSERT(NodeId(k) != node_id); | 6672 ASSERT(DeoptId(k) != deopt_id); |
6673 } | 6673 } |
6674 ASSERT(pc != PC(k)); | 6674 ASSERT(pc != PC(k)); |
6675 } | 6675 } |
6676 } | 6676 } |
6677 } | 6677 } |
6678 #endif // DEBUG | 6678 #endif // DEBUG |
6679 } | 6679 } |
6680 | 6680 |
6681 | 6681 |
6682 void Stackmap::SetCode(const Code& code) const { | 6682 void Stackmap::SetCode(const Code& code) const { |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7189 } | 7189 } |
7190 return Code::null(); | 7190 return Code::null(); |
7191 } | 7191 } |
7192 | 7192 |
7193 | 7193 |
7194 intptr_t Code::GetTokenIndexOfPC(uword pc) const { | 7194 intptr_t Code::GetTokenIndexOfPC(uword pc) const { |
7195 intptr_t token_pos = -1; | 7195 intptr_t token_pos = -1; |
7196 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 7196 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
7197 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 7197 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
7198 if (descriptors.PC(i) == pc) { | 7198 if (descriptors.PC(i) == pc) { |
7199 token_pos = descriptors.TokenIndex(i); | 7199 token_pos = descriptors.TokenPos(i); |
7200 break; | 7200 break; |
7201 } | 7201 } |
7202 } | 7202 } |
7203 return token_pos; | 7203 return token_pos; |
7204 } | 7204 } |
7205 | 7205 |
7206 | 7206 |
7207 uword Code::GetDeoptPcAtNodeId(intptr_t node_id) const { | 7207 uword Code::GetDeoptPcAtDeoptId(intptr_t deopt_id) const { |
7208 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 7208 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
7209 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 7209 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
7210 if ((descriptors.NodeId(i) == node_id) && | 7210 if ((descriptors.DeoptId(i) == deopt_id) && |
7211 (descriptors.DescriptorKind(i) == PcDescriptors::kDeopt)) { | 7211 (descriptors.DescriptorKind(i) == PcDescriptors::kDeopt)) { |
7212 return descriptors.PC(i); | 7212 return descriptors.PC(i); |
7213 } | 7213 } |
7214 } | 7214 } |
7215 return 0; | 7215 return 0; |
7216 } | 7216 } |
7217 | 7217 |
7218 | 7218 |
7219 const char* Code::ToCString() const { | 7219 const char* Code::ToCString() const { |
7220 const char* kFormat = "Code entry:0x%d"; | 7220 const char* kFormat = "Code entry:0x%d"; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7252 GrowableArray<intptr_t>* node_ids, | 7252 GrowableArray<intptr_t>* node_ids, |
7253 const GrowableObjectArray& ic_data_objs) const { | 7253 const GrowableObjectArray& ic_data_objs) const { |
7254 ASSERT(node_ids != NULL); | 7254 ASSERT(node_ids != NULL); |
7255 ASSERT(!ic_data_objs.IsNull()); | 7255 ASSERT(!ic_data_objs.IsNull()); |
7256 const PcDescriptors& descriptors = | 7256 const PcDescriptors& descriptors = |
7257 PcDescriptors::Handle(this->pc_descriptors()); | 7257 PcDescriptors::Handle(this->pc_descriptors()); |
7258 ICData& ic_data_obj = ICData::Handle(); | 7258 ICData& ic_data_obj = ICData::Handle(); |
7259 intptr_t max_id = -1; | 7259 intptr_t max_id = -1; |
7260 for (intptr_t i = 0; i < descriptors.Length(); i++) { | 7260 for (intptr_t i = 0; i < descriptors.Length(); i++) { |
7261 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { | 7261 if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) { |
7262 intptr_t node_id = descriptors.NodeId(i); | 7262 intptr_t deopt_id = descriptors.DeoptId(i); |
7263 if (node_id > max_id) { | 7263 if (deopt_id > max_id) { |
7264 max_id = node_id; | 7264 max_id = deopt_id; |
7265 } | 7265 } |
7266 node_ids->Add(node_id); | 7266 node_ids->Add(deopt_id); |
7267 ic_data_obj = CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)); | 7267 ic_data_obj = CodePatcher::GetInstanceCallIcDataAt(descriptors.PC(i)); |
7268 ic_data_objs.Add(ic_data_obj); | 7268 ic_data_objs.Add(ic_data_obj); |
7269 } | 7269 } |
7270 } | 7270 } |
7271 return max_id; | 7271 return max_id; |
7272 } | 7272 } |
7273 | 7273 |
7274 | 7274 |
7275 RawStackmap* Code::GetStackmap(uword pc, Array* maps, Stackmap* map) const { | 7275 RawStackmap* Code::GetStackmap(uword pc, Array* maps, Stackmap* map) const { |
7276 // This code is used during iterating frames during a GC and hence it | 7276 // This code is used during iterating frames during a GC and hence it |
(...skipping 3768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11045 const char* JSRegExp::ToCString() const { | 11045 const char* JSRegExp::ToCString() const { |
11046 const String& str = String::Handle(pattern()); | 11046 const String& str = String::Handle(pattern()); |
11047 const char* format = "JSRegExp: pattern=%s flags=%s"; | 11047 const char* format = "JSRegExp: pattern=%s flags=%s"; |
11048 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 11048 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
11049 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 11049 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
11050 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 11050 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
11051 return chars; | 11051 return chars; |
11052 } | 11052 } |
11053 | 11053 |
11054 } // namespace dart | 11054 } // namespace dart |
OLD | NEW |