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

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

Issue 8357034: Transitioning to new IC structure: change IC data to include function name; pass IC data instead ... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 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
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5 #include "vm/ic_stubs.h"
6
7 #include "vm/object.h"
8
9 namespace dart {
10
11 ICData::ICData(const Code& ic_stub) : ic_stub_(ic_stub) {
12 ASSERT(!ic_stub_.IsNull());
13 }
14
15
16 intptr_t ICData::NumberOfClasses() const {
17 const Array& data = Array::Handle(ic_stub_.ic_data());
18 Smi& smi = Smi::Handle();
19 smi ^= data.At(0);
20 return smi.Value();
21 }
22
23
24 intptr_t ICData::NumberOfChecks() const {
25 intptr_t number_of_classes = NumberOfClasses();
26 const Array& data = Array::Handle(ic_stub_.ic_data());
27 intptr_t length = data.Length();
28 // First element is number of classes (N), followed by a group of elements,
29 // each element consisting of N classes + 1 target.
30 // Subtract the terminating NULL group.
31 return (length - 1) / (number_of_classes + 1) - 1;
32 }
33
34
35 void ICData::GetCheckAt(intptr_t index,
36 GrowableArray<const Class*>* classes,
37 Function* target) const {
38 ASSERT(classes != NULL);
39 ASSERT(target != NULL);
40 ASSERT((0 <= index) && (index < NumberOfChecks()));
41 classes->Clear();
42 const Array& data = Array::Handle(ic_stub_.ic_data());
43 intptr_t num_classes = NumberOfClasses();
44 intptr_t pos = 1 + (num_classes + 1) * index;
45 for (intptr_t i = 0; i < num_classes; i++) {
46 Class& cls = Class::ZoneHandle();
47 cls ^= data.At(pos++);
48 classes->Add(&cls);
49 }
50 (*target) ^= data.At(pos);
51 }
52
53
54 void ICData::SetCheckAt(intptr_t index,
55 const GrowableArray<const Class*>& classes,
56 const Function& target) {
57 ASSERT((0 <= index) && (index < NumberOfChecks()));
58 const Array& data = Array::Handle(ic_stub_.ic_data());
59 intptr_t num_classes = NumberOfClasses();
60 intptr_t pos = 1 + (num_classes + 1) * index;
61 for (intptr_t i = 0; i < num_classes; i++) {
62 // Null is used as terminating object, do not add it.
63 ASSERT(!classes[i]->IsNull());
64 // Contract says that no null classes may be added.
65 ASSERT(!classes[i]->IsNullClass());
66 data.SetAt(pos++, *(classes[i]));
67 }
68 ASSERT(!target.IsNull());
69 // Null is used as terminating object, do not add it.
70 data.SetAt(pos, target);
71 }
72
73
74 void ICData::AddCheck(const GrowableArray<const Class*>& classes,
75 const Function& target) {
76 const Array& data = Array::Handle(ic_stub_.ic_data());
77 ASSERT(classes.length() == NumberOfClasses());
78 intptr_t number_of_checks = NumberOfChecks();
79 intptr_t new_len = data.Length() + classes.length() + 1;
80 const Array& new_data = Array::Handle(Array::Grow(data, new_len, Heap::kOld));
81 ic_stub_.set_ic_data(new_data);
82 SetCheckAt(number_of_checks, classes, target);
83 }
84
85
86 void ICData::SetICDataArray(intptr_t num_classes, intptr_t num_checks) {
87 // Add a terminating group to num_checks.
88 intptr_t len = 1 + (num_classes + 1) * (num_checks + 1);
89 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
90 ic_data.SetAt(0, Smi::Handle(Smi::New(num_classes)));
91 ic_stub_.set_ic_data(ic_data);
92 }
93
94
95 void ICData::Print() {
96 intptr_t number_of_checks = NumberOfChecks();
97 GrowableArray<const Class*> temp_classes;
98 Function& temp_target = Function::Handle();
99 for (intptr_t i = 0; i < number_of_checks; i++) {
100 GetCheckAt(i, &temp_classes, &temp_target);
101 for (intptr_t k = 0; k < temp_classes.length(); k++) {
102 OS::Print(" %d. %s\n", k, temp_classes[k]->ToCString());
103 }
104 OS::Print("=> %s\n", temp_target.ToCString());
105 }
106 }
107
108
109 void ICData::ChangeTargets(const Function& from, const Function& to) {
110 if (from.raw() == to.raw()) {
111 return;
112 }
113 intptr_t n = NumberOfChecks();
114 GrowableArray<const Class*> temp_classes;
115 Function& temp_function = Function::Handle();
116 for (int i = 0; i < n; i++) {
117 GetCheckAt(i, &temp_classes, &temp_function);
118 if (temp_function.raw() == from.raw()) {
119 SetCheckAt(i, temp_classes, to);
120 }
121 }
122 }
123
124
125 void ICData::CheckIsSame(const GrowableArray<const Class*>* classes,
126 const GrowableArray<const Function*>* targets) const {
127 ASSERT(NumberOfClasses() == 1); // Test only for 1-class checks.
128 intptr_t number_of_checks = NumberOfChecks();
129 ASSERT((classes == NULL) || (classes->length() == number_of_checks));
130 ASSERT((targets == NULL) || (targets->length() == number_of_checks));
131 if (classes != NULL) {
132 GrowableArray<const Class*> ic_data_classes;
133 GrowableArray<const Code*> ic_data_targets;
134 GrowableArray<const Class*> temp_classes;
135 Function& temp_target = Function::Handle();
136 for (intptr_t i = 0; i < number_of_checks; i++) {
137 GetCheckAt(i, &temp_classes, &temp_target);
138 ASSERT(temp_classes.length() == 1);
139 const Class* cls = temp_classes[0];
140 intptr_t found_at = -1;
141 for (intptr_t k = 0; k < classes->length(); k++) {
142 // Check that all classes exist.
143 if ((*classes)[k]->raw() == cls->raw()) {
144 found_at = k;
145 break;
146 }
147 }
148 ASSERT(found_at != -1);
149 if ((*targets)[found_at]->raw() != temp_target.raw()) {
150 UNREACHABLE();
151 }
152 }
153 }
154 }
155
156 } // namespace dart
157
OLDNEW
« runtime/vm/ic_data.cc ('K') | « runtime/vm/ic_stubs.h ('k') | runtime/vm/ic_stubs_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698