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

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

Issue 10368004: Properly set the element type of literal lists. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 } 863 }
864 864
865 865
866 void CodeGenerator::VisitArrayNode(ArrayNode* node) { 866 void CodeGenerator::VisitArrayNode(ArrayNode* node) {
867 // Evaluate the array elements. 867 // Evaluate the array elements.
868 for (int i = 0; i < node->length(); i++) { 868 for (int i = 0; i < node->length(); i++) {
869 AstNode* element = node->ElementAt(i); 869 AstNode* element = node->ElementAt(i);
870 element->Visit(this); 870 element->Visit(this);
871 } 871 }
872 872
873 const AbstractTypeArguments& element_type = node->type_arguments();
874 const bool instantiate_type_arguments = true;
875 GenerateTypeArguments(node->id(),
876 node->token_index(),
877 element_type,
878 instantiate_type_arguments);
879 __ popq(RBX);
880 __ movq(R10, Immediate(Smi::RawValue(node->length())));
881
873 // Allocate the array. 882 // Allocate the array.
874 // R10 : Array length as Smi. 883 // R10 : Array length as Smi.
875 // RBX : element type for the array. 884 // RBX : element type for the array.
876 __ movq(R10, Immediate(Smi::RawValue(node->length())));
877 const AbstractTypeArguments& element_type = node->type_arguments();
878 ASSERT(element_type.IsNull() || element_type.IsInstantiated());
879 __ LoadObject(RBX, element_type);
880 GenerateCall(node->token_index(), 885 GenerateCall(node->token_index(),
881 &StubCode::AllocateArrayLabel(), 886 &StubCode::AllocateArrayLabel(),
882 PcDescriptors::kOther); 887 PcDescriptors::kOther);
883 888
884 // Pop the element values from the stack into the array. 889 // Pop the element values from the stack into the array.
885 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); 890 __ leaq(RCX, FieldAddress(RAX, Array::data_offset()));
886 for (int i = node->length() - 1; i >= 0; i--) { 891 for (int i = node->length() - 1; i >= 0; i--) {
887 __ popq(Address(RCX, i * kWordSize)); 892 __ popq(Address(RCX, i * kWordSize));
888 } 893 }
889 894
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 intptr_t type_arguments_instance_field_offset = 2150 intptr_t type_arguments_instance_field_offset =
2146 instantiator_class.type_arguments_instance_field_offset(); 2151 instantiator_class.type_arguments_instance_field_offset();
2147 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 2152 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
2148 __ movq(RAX, FieldAddress(RAX, type_arguments_instance_field_offset)); 2153 __ movq(RAX, FieldAddress(RAX, type_arguments_instance_field_offset));
2149 __ pushq(RAX); 2154 __ pushq(RAX);
2150 } 2155 }
2151 } 2156 }
2152 } 2157 }
2153 2158
2154 2159
2155 // Pushes the type arguments on the stack in preparation of a constructor or 2160 // Pushes the type arguments on the stack in preparation of an allocation call.
2156 // factory call. 2161 // If instantiate_type_arguments is true, the instantiated type arguments
2157 // For a factory call, instantiates (possibly requiring an additional run time 2162 // are pushed on the stack (after an instantiation run time call, if necessary).
2158 // call) and pushes the type argument vector that will be passed as implicit 2163 // If instantiate_type_arguments is false, the (possibly uninstantiated) type
2159 // first parameter to the factory. 2164 // arguments are pushed on the stack, as well as the type arguments of the
2160 // For a constructor call allocating an object of a parameterized class, pushes 2165 // instantiator (or the special kNoInstantiator Smi marker, if the type
2161 // the type arguments and the type arguments of the instantiator, without ever 2166 // arguments are instantiated).
2162 // generating an additional run time call. 2167 void CodeGenerator::GenerateTypeArguments(
2163 // Does nothing for a constructor call allocating an object of a non 2168 intptr_t node_id,
2164 // parameterized class. 2169 intptr_t token_index,
2165 // Note that a class without proper type parameters may still be parameterized, 2170 const AbstractTypeArguments& type_arguments,
2166 // e.g. class A extends Array<int>. 2171 bool instantiate_type_arguments) {
2167 void CodeGenerator::GenerateTypeArguments(ConstructorCallNode* node,
2168 bool requires_type_arguments) {
2169 const Immediate raw_null = 2172 const Immediate raw_null =
2170 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2173 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2171 // Instantiate the type arguments if necessary. 2174 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2172 if (node->type_arguments().IsNull() || 2175 // The type arguments are instantiated.
2173 node->type_arguments().IsInstantiated()) { 2176 __ PushObject(type_arguments);
2174 if (requires_type_arguments) { 2177 if (!instantiate_type_arguments) {
2175 // A factory requires the type arguments as first parameter. 2178 // The type arguments of the instantiator are not needed, since the
2176 __ PushObject(node->type_arguments()); 2179 // type arguments are instantiated.
2177 if (!node->constructor().IsFactory()) { 2180 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2178 // The non-factory allocator additionally requires the instantiator
2179 // type arguments which are not needed here, since the type arguments
2180 // are instantiated.
2181 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2182 }
2183 } 2181 }
2184 } else { 2182 } else {
2185 // The type arguments are uninstantiated. 2183 // The type arguments are uninstantiated.
2186 ASSERT(requires_type_arguments); 2184 GenerateInstantiatorTypeArguments(token_index);
2187 GenerateInstantiatorTypeArguments(node->token_index());
2188 __ popq(RAX); // Pop instantiator. 2185 __ popq(RAX); // Pop instantiator.
2189 // RAX is the instantiator AbstractTypeArguments object (or null). 2186 // RAX is the instantiator AbstractTypeArguments object (or null).
2190 // If the instantiator is null and if the type argument vector 2187 // If the instantiator is null and if the type argument vector
2191 // instantiated from null becomes a vector of Dynamic, then use null as 2188 // instantiated from null becomes a vector of Dynamic, then use null as
2192 // the type arguments. 2189 // the type arguments.
2193 Label type_arguments_instantiated; 2190 Label type_arguments_instantiated;
2194 const intptr_t len = node->type_arguments().Length(); 2191 const intptr_t len = type_arguments.Length();
2195 if (node->type_arguments().IsRawInstantiatedRaw(len)) { 2192 if (type_arguments.IsRawInstantiatedRaw(len)) {
2196 __ cmpq(RAX, raw_null); 2193 __ cmpq(RAX, raw_null);
2197 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2194 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2198 } 2195 }
2199 // Instantiate non-null type arguments. 2196 // Instantiate non-null type arguments.
2200 if (node->type_arguments().IsUninstantiatedIdentity()) { 2197 if (type_arguments.IsUninstantiatedIdentity()) {
2201 // Check if the instantiator type argument vector is a TypeArguments of a 2198 // Check if the instantiator type argument vector is a TypeArguments of a
2202 // matching length and, if so, use it as the instantiated type_arguments. 2199 // matching length and, if so, use it as the instantiated type_arguments.
2203 // No need to check RAX for null (again), because a null instance will 2200 // No need to check RAX for null (again), because a null instance will
2204 // have the wrong class (Null instead of TypeArguments). 2201 // have the wrong class (Null instead of TypeArguments).
2205 Label type_arguments_uninstantiated; 2202 Label type_arguments_uninstantiated;
2206 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 2203 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
2207 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 2204 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
2208 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2205 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2209 Immediate arguments_length =
2210 Immediate(Smi::RawValue(node->type_arguments().Length()));
2211 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 2206 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
2212 arguments_length); 2207 Immediate(Smi::RawValue(len)));
2213 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2208 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2214 __ Bind(&type_arguments_uninstantiated); 2209 __ Bind(&type_arguments_uninstantiated);
2215 } 2210 }
2216 if (node->constructor().IsFactory()) { 2211 if (instantiate_type_arguments) {
2217 // A runtime call to instantiate the type arguments is required before 2212 // A runtime call to instantiate the type arguments is required.
2218 // calling the factory.
2219 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2213 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2220 __ PushObject(node->type_arguments()); 2214 __ PushObject(type_arguments);
2221 __ pushq(RAX); // Push instantiator type arguments. 2215 __ pushq(RAX); // Push instantiator type arguments.
2222 GenerateCallRuntime(node->id(), 2216 GenerateCallRuntime(node_id,
2223 node->token_index(), 2217 token_index,
2224 kInstantiateTypeArgumentsRuntimeEntry); 2218 kInstantiateTypeArgumentsRuntimeEntry);
2225 __ popq(RAX); // Pop instantiator type arguments. 2219 __ popq(RAX); // Pop instantiator type arguments.
2226 __ popq(RAX); // Pop uninstantiated type arguments. 2220 __ popq(RAX); // Pop uninstantiated type arguments.
2227 __ popq(RAX); // Pop instantiated type arguments. 2221 __ popq(RAX); // Pop instantiated type arguments.
2228 __ Bind(&type_arguments_instantiated); 2222 __ Bind(&type_arguments_instantiated);
2229 __ pushq(RAX); // Instantiated type arguments. 2223 __ pushq(RAX); // Instantiated type arguments.
2230 } else { 2224 } else {
2231 // In the non-factory case, we rely on the allocation stub to 2225 // The allocation stub will instantiate the type arguments.
2232 // instantiate the type arguments. 2226 __ PushObject(type_arguments);
2233 __ PushObject(node->type_arguments());
2234 __ pushq(RAX); // Instantiator type arguments. 2227 __ pushq(RAX); // Instantiator type arguments.
2235 Label type_arguments_pushed; 2228 Label type_arguments_pushed;
2236 __ jmp(&type_arguments_pushed, Assembler::kNearJump); 2229 __ jmp(&type_arguments_pushed, Assembler::kNearJump);
2237 2230
2238 __ Bind(&type_arguments_instantiated); 2231 __ Bind(&type_arguments_instantiated);
2239 __ pushq(RAX); // Instantiated type arguments. 2232 __ pushq(RAX); // Instantiated type arguments.
2240 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 2233 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2241 __ Bind(&type_arguments_pushed); 2234 __ Bind(&type_arguments_pushed);
2242 } 2235 }
2243 } 2236 }
2244 } 2237 }
2245 2238
2246 2239
2247 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2240 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2248 if (node->constructor().IsFactory()) { 2241 if (node->constructor().IsFactory()) {
2249 const bool requires_type_arguments = true; // Always first arg to factory. 2242 const bool instantiate_type_arguments = true; // First argument to factory.
2250 GenerateTypeArguments(node, requires_type_arguments); 2243 GenerateTypeArguments(node->id(),
2244 node->token_index(),
2245 node->type_arguments(),
2246 instantiate_type_arguments);
2251 // The top of stack is an instantiated AbstractTypeArguments object 2247 // The top of stack is an instantiated AbstractTypeArguments object
2252 // (or null). 2248 // (or null).
2253 int num_args = node->arguments()->length() + 1; // +1 to include type args. 2249 int num_args = node->arguments()->length() + 1; // +1 to include type args.
2254 node->arguments()->Visit(this); 2250 node->arguments()->Visit(this);
2255 // Call the factory. 2251 // Call the factory.
2256 __ LoadObject(RBX, node->constructor()); 2252 __ LoadObject(RBX, node->constructor());
2257 __ LoadObject(R10, ArgumentsDescriptor(num_args, 2253 __ LoadObject(R10, ArgumentsDescriptor(num_args,
2258 node->arguments()->names())); 2254 node->arguments()->names()));
2259 GenerateCall(node->token_index(), 2255 GenerateCall(node->token_index(),
2260 &StubCode::CallStaticFunctionLabel(), 2256 &StubCode::CallStaticFunctionLabel(),
2261 PcDescriptors::kFuncCall); 2257 PcDescriptors::kFuncCall);
2262 // Factory constructor returns object in RAX. 2258 // Factory constructor returns object in RAX.
2263 __ addq(RSP, Immediate(num_args * kWordSize)); 2259 __ addq(RSP, Immediate(num_args * kWordSize));
2264 if (IsResultNeeded(node)) { 2260 if (IsResultNeeded(node)) {
2265 __ pushq(RAX); 2261 __ pushq(RAX);
2266 } 2262 }
2267 return; 2263 return;
2268 } 2264 }
2269 2265
2270 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 2266 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2271 const bool requires_type_arguments = cls.HasTypeArguments(); 2267 const bool requires_type_arguments = cls.HasTypeArguments();
2272 GenerateTypeArguments(node, requires_type_arguments); 2268 const bool instantiate_type_arguments = false; // Done in stub or runtime.
2269 if (requires_type_arguments) {
2270 GenerateTypeArguments(node->id(),
2271 node->token_index(),
2272 node->type_arguments(),
2273 instantiate_type_arguments);
2274 }
2273 2275
2274 // If cls is parameterized, the type arguments and the instantiator's 2276 // If cls is parameterized, the type arguments and the instantiator's
2275 // type arguments are on the stack. 2277 // type arguments are on the stack.
2276 // In checked mode, if the type arguments are uninstantiated, they may need to 2278 // In checked mode, if the type arguments are uninstantiated, they may need to
2277 // be checked against declared bounds at run time. 2279 // be checked against declared bounds at run time.
2278 Error& malformed_error = Error::Handle(); 2280 Error& malformed_error = Error::Handle();
2279 if (FLAG_enable_type_checks && 2281 if (FLAG_enable_type_checks &&
2280 requires_type_arguments && 2282 requires_type_arguments &&
2281 !node->type_arguments().IsNull() && 2283 !node->type_arguments().IsNull() &&
2282 !node->type_arguments().IsInstantiated() && 2284 !node->type_arguments().IsInstantiated() &&
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 const Error& error = Error::Handle( 2662 const Error& error = Error::Handle(
2661 Parser::FormatError(script, token_index, "Error", format, args)); 2663 Parser::FormatError(script, token_index, "Error", format, args));
2662 va_end(args); 2664 va_end(args);
2663 Isolate::Current()->long_jump_base()->Jump(1, error); 2665 Isolate::Current()->long_jump_base()->Jump(1, error);
2664 UNREACHABLE(); 2666 UNREACHABLE();
2665 } 2667 }
2666 2668
2667 } // namespace dart 2669 } // namespace dart
2668 2670
2669 #endif // defined TARGET_ARCH_X64 2671 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698