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

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

Issue 9939003: Use null type argument vector instead of vector of Dynamic for a generic raw (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 const Function& function = Function::CheckedHandle(arguments.At(0)); 107 const Function& function = Function::CheckedHandle(arguments.At(0));
108 const String& function_name = String::Handle(function.name()); 108 const String& function_name = String::Handle(function.name());
109 const String& class_name = 109 const String& class_name =
110 String::Handle(Class::Handle(function.owner()).Name()); 110 String::Handle(Class::Handle(function.owner()).Name());
111 OS::Print("< Exiting '%s.%s'\n", 111 OS::Print("< Exiting '%s.%s'\n",
112 class_name.ToCString(), function_name.ToCString()); 112 class_name.ToCString(), function_name.ToCString());
113 } 113 }
114 114
115 115
116 // Allocation of a fixed length array of given element type. 116 // Allocation of a fixed length array of given element type.
117 // TODO(regis): This runtime entry is never called for allocating a List of a
118 // generic type, which does not seem correct. Verify that generic user Lists are
119 // properly supported.
117 // Arg0: array length. 120 // Arg0: array length.
118 // Arg1: array element type. 121 // Arg1: array element type.
119 // Arg2: type arguments of the instantiator.
120 // Return value: newly allocated array of length arg0. 122 // Return value: newly allocated array of length arg0.
121 DEFINE_RUNTIME_ENTRY(AllocateArray, 3) { 123 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) {
122 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); 124 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count());
123 const Smi& length = Smi::CheckedHandle(arguments.At(0)); 125 const Smi& length = Smi::CheckedHandle(arguments.At(0));
124 const Array& array = Array::Handle(Array::New(length.Value())); 126 const Array& array = Array::Handle(Array::New(length.Value()));
125 arguments.SetReturn(array); 127 arguments.SetReturn(array);
126 AbstractTypeArguments& element_type = 128 AbstractTypeArguments& element_type =
127 AbstractTypeArguments::CheckedHandle(arguments.At(1)); 129 AbstractTypeArguments::CheckedHandle(arguments.At(1));
128 if (element_type.IsNull()) { 130 // An Array is raw or takes only one type argument.
129 // No instantiator required for a raw type. 131 ASSERT(element_type.IsNull() || (element_type.Length() == 1));
130 ASSERT(AbstractTypeArguments::CheckedHandle(arguments.At(2)).IsNull()); 132 array.SetTypeArguments(element_type); // May be null.
131 return;
132 }
133 // An Array takes only one type argument.
134 ASSERT(element_type.Length() == 1);
135 const AbstractTypeArguments& instantiator =
136 AbstractTypeArguments::CheckedHandle(arguments.At(2));
137 if (instantiator.IsNull()) {
138 // Either the type element is instantiated (use it), or the instantiator is
139 // of a raw type and we cannot instantiate the element type (leave as null).
140 if (element_type.IsInstantiated()) {
141 array.SetTypeArguments(element_type);
142 }
143 return;
144 }
145 ASSERT(!element_type.IsInstantiated());
146 // If possible, use the instantiator as the type argument vector.
147 if (element_type.IsUninstantiatedIdentity() && (instantiator.Length() == 1)) {
148 // No need to check that the instantiator is a TypeArguments, since the
149 // virtual call to Length() handles other cases that are harder to inline.
150 element_type = instantiator.raw();
151 } else {
152 element_type = InstantiatedTypeArguments::New(element_type, instantiator);
153 }
154 array.SetTypeArguments(element_type);
155 } 133 }
156 134
157 135
158 // Allocate a new object. 136 // Allocate a new object.
159 // Arg0: class of the object that needs to be allocated. 137 // Arg0: class of the object that needs to be allocated.
160 // Arg1: type arguments of the object that needs to be allocated. 138 // Arg1: type arguments of the object that needs to be allocated.
161 // Arg2: type arguments of the instantiator. 139 // Arg2: type arguments of the instantiator or kNoInstantiator.
162 // Return value: newly allocated object. 140 // Return value: newly allocated object.
163 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { 141 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) {
164 ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count()); 142 ASSERT(arguments.Count() == kAllocateObjectRuntimeEntry.argument_count());
165 const Class& cls = Class::CheckedHandle(arguments.At(0)); 143 const Class& cls = Class::CheckedHandle(arguments.At(0));
166 const Instance& instance = Instance::Handle(Instance::New(cls)); 144 const Instance& instance = Instance::Handle(Instance::New(cls));
167 arguments.SetReturn(instance); 145 arguments.SetReturn(instance);
168 if (!cls.HasTypeArguments()) { 146 if (!cls.HasTypeArguments()) {
169 // No type arguments required for a non-parameterized type. 147 // No type arguments required for a non-parameterized type.
170 ASSERT(Instance::CheckedHandle(arguments.At(1)).IsNull()); 148 ASSERT(Instance::CheckedHandle(arguments.At(1)).IsNull());
171 return; 149 return;
172 } 150 }
173 AbstractTypeArguments& type_arguments = 151 AbstractTypeArguments& type_arguments =
174 AbstractTypeArguments::CheckedHandle(arguments.At(1)); 152 AbstractTypeArguments::CheckedHandle(arguments.At(1));
175 if (type_arguments.IsNull()) { 153 ASSERT(type_arguments.IsNull() ||
176 // No instantiator is required for a raw type. 154 (type_arguments.Length() == cls.NumTypeArguments()));
177 ASSERT(Instance::CheckedHandle(arguments.At(2)).IsNull()); 155 // If no instantiator is provided, set the type arguments and return.
178 return; 156 if (Object::Handle(arguments.At(2)).IsSmi()) {
179 } 157 ASSERT(Smi::CheckedHandle(arguments.At(2)).Value() ==
180 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); 158 StubCode::kNoInstantiator);
181 const AbstractTypeArguments& instantiator = 159 instance.SetTypeArguments(type_arguments); // May be null.
182 AbstractTypeArguments::CheckedHandle(arguments.At(2));
183 if (instantiator.IsNull()) {
184 // Either the type argument vector is instantiated (use it), or the
185 // instantiator is of a raw type and we cannot instantiate the type argument
186 // vector (leave it as null).
187 if (type_arguments.IsInstantiated()) {
188 instance.SetTypeArguments(type_arguments);
189 }
190 return; 160 return;
191 } 161 }
192 ASSERT(!type_arguments.IsInstantiated()); 162 ASSERT(!type_arguments.IsInstantiated());
193 // If possible, use the instantiator as the type argument vector. 163 const AbstractTypeArguments& instantiator =
194 if (instantiator.IsTypeArguments()) { 164 AbstractTypeArguments::CheckedHandle(arguments.At(2));
165 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
166 if (instantiator.IsNull()) {
167 type_arguments =
168 InstantiatedTypeArguments::New(type_arguments, instantiator);
169 } else if (instantiator.IsTypeArguments()) {
195 // Code inlined in the caller should have optimized the case where the 170 // Code inlined in the caller should have optimized the case where the
196 // instantiator is a TypeArguments and can be used as type argument vector. 171 // instantiator is a TypeArguments and can be used as type argument vector.
197 ASSERT(!type_arguments.IsUninstantiatedIdentity() || 172 ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
198 (instantiator.Length() != type_arguments.Length())); 173 (instantiator.Length() != type_arguments.Length()));
199 type_arguments = 174 type_arguments =
200 InstantiatedTypeArguments::New(type_arguments, instantiator); 175 InstantiatedTypeArguments::New(type_arguments, instantiator);
201 } else { 176 } else {
177 // If possible, use the instantiator as the type argument vector.
202 if (type_arguments.IsUninstantiatedIdentity() && 178 if (type_arguments.IsUninstantiatedIdentity() &&
203 (instantiator.Length() == type_arguments.Length())) { 179 (instantiator.Length() == type_arguments.Length())) {
204 type_arguments = instantiator.raw(); 180 type_arguments = instantiator.raw();
205 } else { 181 } else {
206 type_arguments = 182 type_arguments =
207 InstantiatedTypeArguments::New(type_arguments, instantiator); 183 InstantiatedTypeArguments::New(type_arguments, instantiator);
208 } 184 }
209 } 185 }
186 ASSERT(type_arguments.IsInstantiated());
210 instance.SetTypeArguments(type_arguments); 187 instance.SetTypeArguments(type_arguments);
211 } 188 }
212 189
213 190
214 // Instantiate type arguments. 191 // Instantiate type arguments.
215 // Arg0: uninstantiated type arguments. 192 // Arg0: uninstantiated type arguments.
216 // Arg1: instantiator type arguments. 193 // Arg1: instantiator type arguments.
217 // Return value: instantiated type arguments. 194 // Return value: instantiated type arguments.
218 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { 195 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) {
219 ASSERT(arguments.Count() == 196 ASSERT(arguments.Count() ==
220 kInstantiateTypeArgumentsRuntimeEntry.argument_count()); 197 kInstantiateTypeArgumentsRuntimeEntry.argument_count());
221 AbstractTypeArguments& type_arguments = 198 AbstractTypeArguments& type_arguments =
222 AbstractTypeArguments::CheckedHandle(arguments.At(0)); 199 AbstractTypeArguments::CheckedHandle(arguments.At(0));
223 const AbstractTypeArguments& instantiator = 200 const AbstractTypeArguments& instantiator =
224 AbstractTypeArguments::CheckedHandle(arguments.At(1)); 201 AbstractTypeArguments::CheckedHandle(arguments.At(1));
225 ASSERT(!type_arguments.IsNull() && 202 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated());
226 !type_arguments.IsInstantiated() && 203 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
227 !instantiator.IsNull());
228 // Code inlined in the caller should have optimized the case where the 204 // Code inlined in the caller should have optimized the case where the
229 // instantiator can be used as type argument vector. 205 // instantiator can be used as type argument vector.
230 ASSERT(!type_arguments.IsUninstantiatedIdentity() || 206 ASSERT(instantiator.IsNull() ||
207 !type_arguments.IsUninstantiatedIdentity() ||
231 !instantiator.IsTypeArguments() || 208 !instantiator.IsTypeArguments() ||
232 (instantiator.Length() != type_arguments.Length())); 209 (instantiator.Length() != type_arguments.Length()));
233 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator); 210 type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator);
211 ASSERT(type_arguments.IsInstantiated());
234 arguments.SetReturn(type_arguments); 212 arguments.SetReturn(type_arguments);
235 } 213 }
236 214
237 215
238 // Allocate a new closure. 216 // Allocate a new closure.
217 // The type argument vector of a closure is always the vector of type parameters
218 // of its signature class, i.e. an uninstantiated identity vector. Therefore,
219 // the instantiator type arguments can be used as the instantiated closure type
220 // arguments and is passed here as the type arguments.
239 // Arg0: local function. 221 // Arg0: local function.
240 // Arg1: type arguments of the closure. 222 // Arg1: type arguments of the closure (i.e. instantiator).
241 // Return value: newly allocated closure. 223 // Return value: newly allocated closure.
242 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) { 224 DEFINE_RUNTIME_ENTRY(AllocateClosure, 2) {
243 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count()); 225 ASSERT(arguments.Count() == kAllocateClosureRuntimeEntry.argument_count());
244 const Function& function = Function::CheckedHandle(arguments.At(0)); 226 const Function& function = Function::CheckedHandle(arguments.At(0));
245 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); 227 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction());
246 const AbstractTypeArguments& type_arguments = 228 const AbstractTypeArguments& type_arguments =
247 AbstractTypeArguments::CheckedHandle(arguments.At(1)); 229 AbstractTypeArguments::CheckedHandle(arguments.At(1));
248 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); 230 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
249 // The current context was saved in the Isolate structure when entering the 231 // The current context was saved in the Isolate structure when entering the
250 // runtime. 232 // runtime.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 393 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
412 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 394 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
413 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 395 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
414 396
415 Error& malformed_error = Error::Handle(); 397 Error& malformed_error = Error::Handle();
416 const bool is_instance_of = src_instance.IsInstanceOf( 398 const bool is_instance_of = src_instance.IsInstanceOf(
417 dst_type, dst_type_instantiator, &malformed_error); 399 dst_type, dst_type_instantiator, &malformed_error);
418 400
419 if (FLAG_trace_type_checks) { 401 if (FLAG_trace_type_checks) {
420 const Type& src_type = Type::Handle(src_instance.GetType()); 402 const Type& src_type = Type::Handle(src_instance.GetType());
403 ASSERT(src_type.IsInstantiated());
421 if (dst_type.IsInstantiated()) { 404 if (dst_type.IsInstantiated()) {
422 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s'.\n", 405 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s'.\n",
423 String::Handle(src_type.Name()).ToCString(), 406 String::Handle(src_type.Name()).ToCString(),
424 is_instance_of ? "is" : "is not", 407 is_instance_of ? "is" : "is not",
425 String::Handle(dst_type.Name()).ToCString(), 408 String::Handle(dst_type.Name()).ToCString(),
426 dst_name.ToCString()); 409 dst_name.ToCString());
427 } else { 410 } else {
428 // Instantiate dst_type before printing. 411 // Instantiate dst_type before printing.
429 const AbstractType& instantiated_dst_type = AbstractType::Handle( 412 const AbstractType& instantiated_dst_type = AbstractType::Handle(
430 dst_type.InstantiateFrom(dst_type_instantiator)); 413 dst_type.InstantiateFrom(dst_type_instantiator));
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 } 1396 }
1414 } 1397 }
1415 } 1398 }
1416 // The cache is null terminated, therefore the loop above should never 1399 // The cache is null terminated, therefore the loop above should never
1417 // terminate by itself. 1400 // terminate by itself.
1418 UNREACHABLE(); 1401 UNREACHABLE();
1419 return Code::null(); 1402 return Code::null();
1420 } 1403 }
1421 1404
1422 } // namespace dart 1405 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698