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

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

Issue 1263573010: Use zone when allocating handles in FlowGraphCompiler assembling operations. Add profiling VM tags… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: sync Created 5 years, 4 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/intermediate_language.h » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 intptr_t slot_ix = 0; 91 intptr_t slot_ix = 0;
92 Environment* current = deopt_env_; 92 Environment* current = deopt_env_;
93 93
94 // Emit all kMaterializeObject instructions describing objects to be 94 // Emit all kMaterializeObject instructions describing objects to be
95 // materialized on the deoptimization as a prefix to the deoptimization info. 95 // materialized on the deoptimization as a prefix to the deoptimization info.
96 EmitMaterializations(deopt_env_, builder); 96 EmitMaterializations(deopt_env_, builder);
97 97
98 // The real frame starts here. 98 // The real frame starts here.
99 builder->MarkFrameStart(); 99 builder->MarkFrameStart();
100 100
101 Zone* zone = compiler->zone();
102
101 // Current PP, FP, and PC. 103 // Current PP, FP, and PC.
102 builder->AddPp(Function::Handle(current->code().function()), slot_ix++); 104 builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
103 builder->AddPcMarker(Function::Handle(), slot_ix++); 105 builder->AddPcMarker(Function::Handle(zone), slot_ix++);
104 builder->AddCallerFp(slot_ix++); 106 builder->AddCallerFp(slot_ix++);
105 builder->AddReturnAddress(Function::Handle(current->code().function()), 107 builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
106 deopt_id(), 108 deopt_id(),
107 slot_ix++); 109 slot_ix++);
108 110
109 // Emit all values that are needed for materialization as a part of the 111 // Emit all values that are needed for materialization as a part of the
110 // expression stack for the bottom-most frame. This guarantees that GC 112 // expression stack for the bottom-most frame. This guarantees that GC
111 // will be able to find them during materialization. 113 // will be able to find them during materialization.
112 slot_ix = builder->EmitMaterializationArguments(slot_ix); 114 slot_ix = builder->EmitMaterializationArguments(slot_ix);
113 115
114 // For the innermost environment, set outgoing arguments and the locals. 116 // For the innermost environment, set outgoing arguments and the locals.
115 for (intptr_t i = current->Length() - 1; 117 for (intptr_t i = current->Length() - 1;
116 i >= current->fixed_parameter_count(); 118 i >= current->fixed_parameter_count();
117 i--) { 119 i--) {
118 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 120 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
119 } 121 }
120 122
121 Environment* previous = current; 123 Environment* previous = current;
122 current = current->outer(); 124 current = current->outer();
123 while (current != NULL) { 125 while (current != NULL) {
124 // PP, FP, and PC. 126 // PP, FP, and PC.
125 builder->AddPp(Function::Handle(current->code().function()), slot_ix++); 127 builder->AddPp(Function::Handle(zone, current->code().function()),
126 builder->AddPcMarker(Function::Handle(previous->code().function()), 128 slot_ix++);
129 builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
127 slot_ix++); 130 slot_ix++);
128 builder->AddCallerFp(slot_ix++); 131 builder->AddCallerFp(slot_ix++);
129 132
130 // For any outer environment the deopt id is that of the call instruction 133 // For any outer environment the deopt id is that of the call instruction
131 // which is recorded in the outer environment. 134 // which is recorded in the outer environment.
132 builder->AddReturnAddress(Function::Handle(current->code().function()), 135 builder->AddReturnAddress(
133 Isolate::ToDeoptAfter(current->deopt_id()), 136 Function::Handle(zone, current->code().function()),
134 slot_ix++); 137 Isolate::ToDeoptAfter(current->deopt_id()),
138 slot_ix++);
135 139
136 // The values of outgoing arguments can be changed from the inlined call so 140 // The values of outgoing arguments can be changed from the inlined call so
137 // we must read them from the previous environment. 141 // we must read them from the previous environment.
138 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 142 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
139 builder->AddCopy(previous->ValueAt(i), 143 builder->AddCopy(previous->ValueAt(i),
140 previous->LocationAt(i), 144 previous->LocationAt(i),
141 slot_ix++); 145 slot_ix++);
142 } 146 }
143 147
144 // Set the locals, note that outgoing arguments are not in the environment. 148 // Set the locals, note that outgoing arguments are not in the environment.
145 for (intptr_t i = current->Length() - 1; 149 for (intptr_t i = current->Length() - 1;
146 i >= current->fixed_parameter_count(); 150 i >= current->fixed_parameter_count();
147 i--) { 151 i--) {
148 builder->AddCopy(current->ValueAt(i), 152 builder->AddCopy(current->ValueAt(i),
149 current->LocationAt(i), 153 current->LocationAt(i),
150 slot_ix++); 154 slot_ix++);
151 } 155 }
152 156
153 // Iterate on the outer environment. 157 // Iterate on the outer environment.
154 previous = current; 158 previous = current;
155 current = current->outer(); 159 current = current->outer();
156 } 160 }
157 // The previous pointer is now the outermost environment. 161 // The previous pointer is now the outermost environment.
158 ASSERT(previous != NULL); 162 ASSERT(previous != NULL);
159 163
160 // For the outermost environment, set caller PC, caller PP, and caller FP. 164 // For the outermost environment, set caller PC, caller PP, and caller FP.
161 builder->AddCallerPp(slot_ix++); 165 builder->AddCallerPp(slot_ix++);
162 // PC marker. 166 // PC marker.
163 builder->AddPcMarker(Function::Handle(previous->code().function()), 167 builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
164 slot_ix++); 168 slot_ix++);
165 builder->AddCallerFp(slot_ix++); 169 builder->AddCallerFp(slot_ix++);
166 builder->AddCallerPc(slot_ix++); 170 builder->AddCallerPc(slot_ix++);
167 171
168 // For the outermost environment, set the incoming arguments. 172 // For the outermost environment, set the incoming arguments.
169 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 173 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
170 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); 174 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
171 } 175 }
172 176
173 return builder->CreateDeoptInfo(deopt_table); 177 return builder->CreateDeoptInfo(deopt_table);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 218
215 // Clobbers RCX. 219 // Clobbers RCX.
216 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( 220 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
217 TypeTestStubKind test_kind, 221 TypeTestStubKind test_kind,
218 Register instance_reg, 222 Register instance_reg,
219 Register type_arguments_reg, 223 Register type_arguments_reg,
220 Register temp_reg, 224 Register temp_reg,
221 Label* is_instance_lbl, 225 Label* is_instance_lbl,
222 Label* is_not_instance_lbl) { 226 Label* is_not_instance_lbl) {
223 const SubtypeTestCache& type_test_cache = 227 const SubtypeTestCache& type_test_cache =
224 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 228 SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
225 __ LoadUniqueObject(temp_reg, type_test_cache); 229 __ LoadUniqueObject(temp_reg, type_test_cache);
226 __ pushq(temp_reg); // Subtype test cache. 230 __ pushq(temp_reg); // Subtype test cache.
227 __ pushq(instance_reg); // Instance. 231 __ pushq(instance_reg); // Instance.
228 if (test_kind == kTestTypeOneArg) { 232 if (test_kind == kTestTypeOneArg) {
229 ASSERT(type_arguments_reg == kNoRegister); 233 ASSERT(type_arguments_reg == kNoRegister);
230 __ PushObject(Object::null_object()); 234 __ PushObject(Object::null_object());
231 __ Call(&StubCode::Subtype1TestCacheLabel()); 235 __ Call(&StubCode::Subtype1TestCacheLabel());
232 } else if (test_kind == kTestTypeTwoArgs) { 236 } else if (test_kind == kTestTypeTwoArgs) {
233 ASSERT(type_arguments_reg == kNoRegister); 237 ASSERT(type_arguments_reg == kNoRegister);
234 __ PushObject(Object::null_object()); 238 __ PushObject(Object::null_object());
(...skipping 21 matching lines...) Expand all
256 // RAX: instance (must survive). 260 // RAX: instance (must survive).
257 // Clobbers R10. 261 // Clobbers R10.
258 RawSubtypeTestCache* 262 RawSubtypeTestCache*
259 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 263 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
260 intptr_t token_pos, 264 intptr_t token_pos,
261 const AbstractType& type, 265 const AbstractType& type,
262 Label* is_instance_lbl, 266 Label* is_instance_lbl,
263 Label* is_not_instance_lbl) { 267 Label* is_not_instance_lbl) {
264 __ Comment("InstantiatedTypeWithArgumentsTest"); 268 __ Comment("InstantiatedTypeWithArgumentsTest");
265 ASSERT(type.IsInstantiated()); 269 ASSERT(type.IsInstantiated());
266 const Class& type_class = Class::ZoneHandle(type.type_class()); 270 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
267 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass()); 271 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
268 const Register kInstanceReg = RAX; 272 const Register kInstanceReg = RAX;
269 Error& malformed_error = Error::Handle(); 273 Error& malformed_error = Error::Handle(zone());
270 const Type& int_type = Type::Handle(Type::IntType()); 274 const Type& int_type = Type::Handle(zone(), Type::IntType());
271 const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error); 275 const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
272 // Malformed type should have been handled at graph construction time. 276 // Malformed type should have been handled at graph construction time.
273 ASSERT(smi_is_ok || malformed_error.IsNull()); 277 ASSERT(smi_is_ok || malformed_error.IsNull());
274 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 278 __ testq(kInstanceReg, Immediate(kSmiTagMask));
275 if (smi_is_ok) { 279 if (smi_is_ok) {
276 __ j(ZERO, is_instance_lbl); 280 __ j(ZERO, is_instance_lbl);
277 } else { 281 } else {
278 __ j(ZERO, is_not_instance_lbl); 282 __ j(ZERO, is_not_instance_lbl);
279 } 283 }
280 const intptr_t num_type_args = type_class.NumTypeArguments(); 284 const intptr_t num_type_args = type_class.NumTypeArguments();
281 const intptr_t num_type_params = type_class.NumTypeParameters(); 285 const intptr_t num_type_params = type_class.NumTypeParameters();
282 const intptr_t from_index = num_type_args - num_type_params; 286 const intptr_t from_index = num_type_args - num_type_params;
283 const TypeArguments& type_arguments = 287 const TypeArguments& type_arguments =
284 TypeArguments::ZoneHandle(type.arguments()); 288 TypeArguments::ZoneHandle(zone(), type.arguments());
285 const bool is_raw_type = type_arguments.IsNull() || 289 const bool is_raw_type = type_arguments.IsNull() ||
286 type_arguments.IsRaw(from_index, num_type_params); 290 type_arguments.IsRaw(from_index, num_type_params);
287 // Signature class is an instantiated parameterized type. 291 // Signature class is an instantiated parameterized type.
288 if (!type_class.IsSignatureClass()) { 292 if (!type_class.IsSignatureClass()) {
289 if (is_raw_type) { 293 if (is_raw_type) {
290 const Register kClassIdReg = R10; 294 const Register kClassIdReg = R10;
291 // dynamic type argument, check only classes. 295 // dynamic type argument, check only classes.
292 __ LoadClassId(kClassIdReg, kInstanceReg); 296 __ LoadClassId(kClassIdReg, kInstanceReg);
293 __ cmpl(kClassIdReg, Immediate(type_class.id())); 297 __ cmpl(kClassIdReg, Immediate(type_class.id()));
294 __ j(EQUAL, is_instance_lbl); 298 __ j(EQUAL, is_instance_lbl);
295 // List is a very common case. 299 // List is a very common case.
296 if (IsListClass(type_class)) { 300 if (IsListClass(type_class)) {
297 GenerateListTypeCheck(kClassIdReg, is_instance_lbl); 301 GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
298 } 302 }
299 return GenerateSubtype1TestCacheLookup( 303 return GenerateSubtype1TestCacheLookup(
300 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); 304 token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
301 } 305 }
302 // If one type argument only, check if type argument is Object or dynamic. 306 // If one type argument only, check if type argument is Object or dynamic.
303 if (type_arguments.Length() == 1) { 307 if (type_arguments.Length() == 1) {
304 const AbstractType& tp_argument = AbstractType::ZoneHandle( 308 const AbstractType& tp_argument = AbstractType::ZoneHandle(zone(),
305 type_arguments.TypeAt(0)); 309 type_arguments.TypeAt(0));
306 ASSERT(!tp_argument.IsMalformed()); 310 ASSERT(!tp_argument.IsMalformed());
307 if (tp_argument.IsType()) { 311 if (tp_argument.IsType()) {
308 ASSERT(tp_argument.HasResolvedTypeClass()); 312 ASSERT(tp_argument.HasResolvedTypeClass());
309 // Check if type argument is dynamic or Object. 313 // Check if type argument is dynamic or Object.
310 const Type& object_type = Type::Handle(Type::ObjectType()); 314 const Type& object_type = Type::Handle(zone(), Type::ObjectType());
311 if (object_type.IsSubtypeOf(tp_argument, NULL)) { 315 if (object_type.IsSubtypeOf(tp_argument, NULL)) {
312 // Instance class test only necessary. 316 // Instance class test only necessary.
313 return GenerateSubtype1TestCacheLookup( 317 return GenerateSubtype1TestCacheLookup(
314 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); 318 token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
315 } 319 }
316 } 320 }
317 } 321 }
318 } 322 }
319 // Regular subtype test cache involving instance's type arguments. 323 // Regular subtype test cache involving instance's type arguments.
320 const Register kTypeArgumentsReg = kNoRegister; 324 const Register kTypeArgumentsReg = kNoRegister;
(...skipping 24 matching lines...) Expand all
345 // RAX: instance to test against (preserved). 349 // RAX: instance to test against (preserved).
346 // Clobbers R10, R13. 350 // Clobbers R10, R13.
347 // Returns true if there is a fallthrough. 351 // Returns true if there is a fallthrough.
348 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 352 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
349 intptr_t token_pos, 353 intptr_t token_pos,
350 const AbstractType& type, 354 const AbstractType& type,
351 Label* is_instance_lbl, 355 Label* is_instance_lbl,
352 Label* is_not_instance_lbl) { 356 Label* is_not_instance_lbl) {
353 __ Comment("InstantiatedTypeNoArgumentsTest"); 357 __ Comment("InstantiatedTypeNoArgumentsTest");
354 ASSERT(type.IsInstantiated()); 358 ASSERT(type.IsInstantiated());
355 const Class& type_class = Class::Handle(type.type_class()); 359 const Class& type_class = Class::Handle(zone(), type.type_class());
356 ASSERT(type_class.NumTypeArguments() == 0); 360 ASSERT(type_class.NumTypeArguments() == 0);
357 361
358 const Register kInstanceReg = RAX; 362 const Register kInstanceReg = RAX;
359 __ testq(kInstanceReg, Immediate(kSmiTagMask)); 363 __ testq(kInstanceReg, Immediate(kSmiTagMask));
360 // If instance is Smi, check directly. 364 // If instance is Smi, check directly.
361 const Class& smi_class = Class::Handle(Smi::Class()); 365 const Class& smi_class = Class::Handle(zone(), Smi::Class());
362 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), 366 if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
363 type_class, 367 type_class,
364 TypeArguments::Handle(), 368 TypeArguments::Handle(zone()),
365 NULL)) { 369 NULL)) {
366 __ j(ZERO, is_instance_lbl); 370 __ j(ZERO, is_instance_lbl);
367 } else { 371 } else {
368 __ j(ZERO, is_not_instance_lbl); 372 __ j(ZERO, is_not_instance_lbl);
369 } 373 }
370 // Compare if the classes are equal. 374 // Compare if the classes are equal.
371 const Register kClassIdReg = R10; 375 const Register kClassIdReg = R10;
372 __ LoadClassId(kClassIdReg, kInstanceReg); 376 __ LoadClassId(kClassIdReg, kInstanceReg);
373 __ cmpl(kClassIdReg, Immediate(type_class.id())); 377 __ cmpl(kClassIdReg, Immediate(type_class.id()));
374 __ j(EQUAL, is_instance_lbl); 378 __ j(EQUAL, is_instance_lbl);
375 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted 379 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted
376 // interfaces. 380 // interfaces.
377 // Bool interface can be implemented only by core class Bool. 381 // Bool interface can be implemented only by core class Bool.
378 if (type.IsBoolType()) { 382 if (type.IsBoolType()) {
379 __ cmpl(kClassIdReg, Immediate(kBoolCid)); 383 __ cmpl(kClassIdReg, Immediate(kBoolCid));
380 __ j(EQUAL, is_instance_lbl); 384 __ j(EQUAL, is_instance_lbl);
381 __ jmp(is_not_instance_lbl); 385 __ jmp(is_not_instance_lbl);
382 return false; 386 return false;
383 } 387 }
384 if (type.IsFunctionType()) { 388 if (type.IsFunctionType()) {
385 // Check if instance is a closure. 389 // Check if instance is a closure.
386 __ LoadClassById(R13, kClassIdReg); 390 __ LoadClassById(R13, kClassIdReg);
387 __ movq(R13, FieldAddress(R13, Class::signature_function_offset())); 391 __ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
388 __ CompareObject(R13, Object::null_object()); 392 __ CompareObject(R13, Object::null_object());
389 __ j(NOT_EQUAL, is_instance_lbl); 393 __ j(NOT_EQUAL, is_instance_lbl);
390 } 394 }
391 // Custom checking for numbers (Smi, Mint, Bigint and Double). 395 // Custom checking for numbers (Smi, Mint, Bigint and Double).
392 // Note that instance is not Smi (checked above). 396 // Note that instance is not Smi (checked above).
393 if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) { 397 if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
394 GenerateNumberTypeCheck( 398 GenerateNumberTypeCheck(
395 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); 399 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
396 return false; 400 return false;
397 } 401 }
398 if (type.IsStringType()) { 402 if (type.IsStringType()) {
399 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); 403 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
400 return false; 404 return false;
401 } 405 }
402 // Otherwise fallthrough. 406 // Otherwise fallthrough.
403 return true; 407 return true;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 // Load instantiator (or null) and instantiator type arguments on stack. 457 // Load instantiator (or null) and instantiator type arguments on stack.
454 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 458 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
455 // RDX: instantiator type arguments. 459 // RDX: instantiator type arguments.
456 // Check if type arguments are null, i.e. equivalent to vector of dynamic. 460 // Check if type arguments are null, i.e. equivalent to vector of dynamic.
457 __ CompareObject(RDX, Object::null_object()); 461 __ CompareObject(RDX, Object::null_object());
458 __ j(EQUAL, is_instance_lbl); 462 __ j(EQUAL, is_instance_lbl);
459 __ movq(RDI, 463 __ movq(RDI,
460 FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index()))); 464 FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
461 // RDI: Concrete type of type. 465 // RDI: Concrete type of type.
462 // Check if type argument is dynamic. 466 // Check if type argument is dynamic.
463 __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType())); 467 __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::DynamicType()));
464 __ j(EQUAL, is_instance_lbl); 468 __ j(EQUAL, is_instance_lbl);
465 const Type& object_type = Type::ZoneHandle(Type::ObjectType()); 469 const Type& object_type = Type::ZoneHandle(zone(), Type::ObjectType());
466 __ CompareObject(RDI, object_type); 470 __ CompareObject(RDI, object_type);
467 __ j(EQUAL, is_instance_lbl); 471 __ j(EQUAL, is_instance_lbl);
468 472
469 // For Smi check quickly against int and num interfaces. 473 // For Smi check quickly against int and num interfaces.
470 Label not_smi; 474 Label not_smi;
471 __ testq(RAX, Immediate(kSmiTagMask)); // Value is Smi? 475 __ testq(RAX, Immediate(kSmiTagMask)); // Value is Smi?
472 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 476 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
473 __ CompareObject(RDI, Type::ZoneHandle(Type::IntType())); 477 __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::IntType()));
474 __ j(EQUAL, is_instance_lbl); 478 __ j(EQUAL, is_instance_lbl);
475 __ CompareObject(RDI, Type::ZoneHandle(Type::Number())); 479 __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::Number()));
476 __ j(EQUAL, is_instance_lbl); 480 __ j(EQUAL, is_instance_lbl);
477 // Smi must be handled in runtime. 481 // Smi must be handled in runtime.
478 Label fall_through; 482 Label fall_through;
479 __ jmp(&fall_through); 483 __ jmp(&fall_through);
480 484
481 __ Bind(&not_smi); 485 __ Bind(&not_smi);
482 // RDX: instantiator type arguments. 486 // RDX: instantiator type arguments.
483 // RAX: instance. 487 // RAX: instance.
484 const Register kInstanceReg = RAX; 488 const Register kInstanceReg = RAX;
485 const Register kTypeArgumentsReg = RDX; 489 const Register kTypeArgumentsReg = RDX;
486 const Register kTempReg = R10; 490 const Register kTempReg = R10;
487 const SubtypeTestCache& type_test_cache = 491 const SubtypeTestCache& type_test_cache =
488 SubtypeTestCache::ZoneHandle( 492 SubtypeTestCache::ZoneHandle(zone(),
489 GenerateCallSubtypeTestStub(kTestTypeThreeArgs, 493 GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
490 kInstanceReg, 494 kInstanceReg,
491 kTypeArgumentsReg, 495 kTypeArgumentsReg,
492 kTempReg, 496 kTempReg,
493 is_instance_lbl, 497 is_instance_lbl,
494 is_not_instance_lbl)); 498 is_not_instance_lbl));
495 __ Bind(&fall_through); 499 __ Bind(&fall_through);
496 return type_test_cache.raw(); 500 return type_test_cache.raw();
497 } 501 }
498 if (type.IsType()) { 502 if (type.IsType()) {
(...skipping 30 matching lines...) Expand all
529 const AbstractType& type, 533 const AbstractType& type,
530 Label* is_instance_lbl, 534 Label* is_instance_lbl,
531 Label* is_not_instance_lbl) { 535 Label* is_not_instance_lbl) {
532 __ Comment("InlineInstanceof"); 536 __ Comment("InlineInstanceof");
533 if (type.IsVoidType()) { 537 if (type.IsVoidType()) {
534 // A non-null value is returned from a void function, which will result in a 538 // A non-null value is returned from a void function, which will result in a
535 // type error. A null value is handled prior to executing this inline code. 539 // type error. A null value is handled prior to executing this inline code.
536 return SubtypeTestCache::null(); 540 return SubtypeTestCache::null();
537 } 541 }
538 if (type.IsInstantiated()) { 542 if (type.IsInstantiated()) {
539 const Class& type_class = Class::ZoneHandle(type.type_class()); 543 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
540 // A class equality check is only applicable with a dst type of a 544 // A class equality check is only applicable with a dst type of a
541 // non-parameterized class, non-signature class, or with a raw dst type of 545 // non-parameterized class, non-signature class, or with a raw dst type of
542 // a parameterized class. 546 // a parameterized class.
543 if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) { 547 if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
544 return GenerateInstantiatedTypeWithArgumentsTest(token_pos, 548 return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
545 type, 549 type,
546 is_instance_lbl, 550 is_instance_lbl,
547 is_not_instance_lbl); 551 is_not_instance_lbl);
548 // Fall through to runtime call. 552 // Fall through to runtime call.
549 } 553 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 // return false here if the instance is null (and if the type is 602 // return false here if the instance is null (and if the type is
599 // instantiated). 603 // instantiated).
600 // We can only inline this null check if the type is instantiated at compile 604 // We can only inline this null check if the type is instantiated at compile
601 // time, since an uninstantiated type at compile time could be Object or 605 // time, since an uninstantiated type at compile time could be Object or
602 // dynamic at run time. 606 // dynamic at run time.
603 __ CompareObject(RAX, Object::null_object()); 607 __ CompareObject(RAX, Object::null_object());
604 __ j(EQUAL, type.IsNullType() ? &is_instance : &is_not_instance); 608 __ j(EQUAL, type.IsNullType() ? &is_instance : &is_not_instance);
605 } 609 }
606 610
607 // Generate inline instanceof test. 611 // Generate inline instanceof test.
608 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 612 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
609 test_cache = GenerateInlineInstanceof(token_pos, type, 613 test_cache = GenerateInlineInstanceof(token_pos, type,
610 &is_instance, &is_not_instance); 614 &is_instance, &is_not_instance);
611 615
612 // test_cache is null if there is no fall-through. 616 // test_cache is null if there is no fall-through.
613 Label done; 617 Label done;
614 if (!test_cache.IsNull()) { 618 if (!test_cache.IsNull()) {
615 // Generate runtime call. 619 // Generate runtime call.
616 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 620 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
617 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. 621 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
618 __ PushObject(Object::null_object()); // Make room for the result. 622 __ PushObject(Object::null_object()); // Make room for the result.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 // We should never return here. 701 // We should never return here.
698 __ int3(); 702 __ int3();
699 703
700 __ Bind(&is_assignable); // For a null object. 704 __ Bind(&is_assignable); // For a null object.
701 __ popq(RDX); // Remove pushed instantiator type arguments. 705 __ popq(RDX); // Remove pushed instantiator type arguments.
702 __ popq(RCX); // Remove pushed instantiator. 706 __ popq(RCX); // Remove pushed instantiator.
703 return; 707 return;
704 } 708 }
705 709
706 // Generate inline type check, linking to runtime call if not assignable. 710 // Generate inline type check, linking to runtime call if not assignable.
707 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 711 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
708 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 712 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
709 &is_assignable, &runtime_call); 713 &is_assignable, &runtime_call);
710 714
711 __ Bind(&runtime_call); 715 __ Bind(&runtime_call);
712 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 716 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
713 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. 717 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
714 __ PushObject(Object::null_object()); // Make room for the result. 718 __ PushObject(Object::null_object()); // Make room for the result.
715 __ pushq(RAX); // Push the source object. 719 __ pushq(RAX); // Push the source object.
716 __ PushObject(dst_type); // Push the type of the destination. 720 __ PushObject(dst_type); // Push the type of the destination.
717 __ pushq(RCX); // Instantiator. 721 __ pushq(RCX); // Instantiator.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 // RAX is arg_pos as Smi. 866 // RAX is arg_pos as Smi.
863 // Point to next named entry. 867 // Point to next named entry.
864 __ AddImmediate( 868 __ AddImmediate(
865 RDI, Immediate(ArgumentsDescriptor::named_entry_size())); 869 RDI, Immediate(ArgumentsDescriptor::named_entry_size()));
866 __ negq(RAX); 870 __ negq(RAX);
867 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi. 871 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi.
868 __ movq(RAX, argument_addr); 872 __ movq(RAX, argument_addr);
869 __ jmp(&assign_optional_parameter, Assembler::kNearJump); 873 __ jmp(&assign_optional_parameter, Assembler::kNearJump);
870 __ Bind(&load_default_value); 874 __ Bind(&load_default_value);
871 // Load RAX with default argument. 875 // Load RAX with default argument.
872 const Object& value = Object::ZoneHandle( 876 const Object& value = Object::ZoneHandle(zone(),
873 parsed_function().default_parameter_values().At( 877 parsed_function().default_parameter_values().At(
874 param_pos - num_fixed_params)); 878 param_pos - num_fixed_params));
875 __ LoadObject(RAX, value); 879 __ LoadObject(RAX, value);
876 __ Bind(&assign_optional_parameter); 880 __ Bind(&assign_optional_parameter);
877 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos]. 881 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos].
878 // We do not use the final allocation index of the variable here, i.e. 882 // We do not use the final allocation index of the variable here, i.e.
879 // scope->VariableAt(i)->index(), because captured variables still need 883 // scope->VariableAt(i)->index(), because captured variables still need
880 // to be copied to the context that is not yet allocated. 884 // to be copied to the context that is not yet allocated.
881 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 885 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
882 const Address param_addr(RBP, computed_param_pos * kWordSize); 886 const Address param_addr(RBP, computed_param_pos * kWordSize);
(...skipping 15 matching lines...) Expand all
898 __ SmiUntag(RCX); 902 __ SmiUntag(RCX);
899 for (int i = 0; i < num_opt_pos_params; i++) { 903 for (int i = 0; i < num_opt_pos_params; i++) {
900 Label next_parameter; 904 Label next_parameter;
901 // Handle this optional positional parameter only if k or fewer positional 905 // Handle this optional positional parameter only if k or fewer positional
902 // arguments have been passed, where k is param_pos, the position of this 906 // arguments have been passed, where k is param_pos, the position of this
903 // optional parameter in the formal parameter list. 907 // optional parameter in the formal parameter list.
904 const int param_pos = num_fixed_params + i; 908 const int param_pos = num_fixed_params + i;
905 __ CompareImmediate(RCX, Immediate(param_pos)); 909 __ CompareImmediate(RCX, Immediate(param_pos));
906 __ j(GREATER, &next_parameter, Assembler::kNearJump); 910 __ j(GREATER, &next_parameter, Assembler::kNearJump);
907 // Load RAX with default argument. 911 // Load RAX with default argument.
908 const Object& value = Object::ZoneHandle( 912 const Object& value = Object::ZoneHandle(zone(),
909 parsed_function().default_parameter_values().At(i)); 913 parsed_function().default_parameter_values().At(i));
910 __ LoadObject(RAX, value); 914 __ LoadObject(RAX, value);
911 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos]. 915 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos].
912 // We do not use the final allocation index of the variable here, i.e. 916 // We do not use the final allocation index of the variable here, i.e.
913 // scope->VariableAt(i)->index(), because captured variables still need 917 // scope->VariableAt(i)->index(), because captured variables still need
914 // to be copied to the context that is not yet allocated. 918 // to be copied to the context that is not yet allocated.
915 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 919 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
916 const Address param_addr(RBP, computed_param_pos * kWordSize); 920 const Address param_addr(RBP, computed_param_pos * kWordSize);
917 __ movq(param_addr, RAX); 921 __ movq(param_addr, RAX);
918 __ Bind(&next_parameter); 922 __ Bind(&next_parameter);
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 } 1242 }
1239 1243
1240 1244
1241 void FlowGraphCompiler::EmitEdgeCounter() { 1245 void FlowGraphCompiler::EmitEdgeCounter() {
1242 // We do not check for overflow when incrementing the edge counter. The 1246 // We do not check for overflow when incrementing the edge counter. The
1243 // function should normally be optimized long before the counter can 1247 // function should normally be optimized long before the counter can
1244 // overflow; and though we do not reset the counters when we optimize or 1248 // overflow; and though we do not reset the counters when we optimize or
1245 // deoptimize, there is a bound on the number of 1249 // deoptimize, there is a bound on the number of
1246 // optimization/deoptimization cycles we will attempt. 1250 // optimization/deoptimization cycles we will attempt.
1247 ASSERT(assembler_->constant_pool_allowed()); 1251 ASSERT(assembler_->constant_pool_allowed());
1248 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); 1252 const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
1249 counter.SetAt(0, Smi::Handle(Smi::New(0))); 1253 counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
1250 __ Comment("Edge counter"); 1254 __ Comment("Edge counter");
1251 __ LoadUniqueObject(RAX, counter); 1255 __ LoadUniqueObject(RAX, counter);
1252 intptr_t increment_start = assembler_->CodeSize(); 1256 intptr_t increment_start = assembler_->CodeSize();
1253 __ IncrementSmiField(FieldAddress(RAX, Array::element_offset(0)), 1); 1257 __ IncrementSmiField(FieldAddress(RAX, Array::element_offset(0)), 1);
1254 int32_t size = assembler_->CodeSize() - increment_start; 1258 int32_t size = assembler_->CodeSize() - increment_start;
1255 if (isolate()->edge_counter_increment_size() == -1) { 1259 if (isolate()->edge_counter_increment_size() == -1) {
1256 isolate()->set_edge_counter_increment_size(size); 1260 isolate()->set_edge_counter_increment_size(size);
1257 } else { 1261 } else {
1258 ASSERT(size == isolate()->edge_counter_increment_size()); 1262 ASSERT(size == isolate()->edge_counter_increment_size());
1259 } 1263 }
1260 } 1264 }
1261 1265
1262 1266
1263 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() { 1267 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() {
1264 const int32_t size = Isolate::Current()->edge_counter_increment_size(); 1268 const int32_t size = Isolate::Current()->edge_counter_increment_size();
1265 ASSERT(size != -1); 1269 ASSERT(size != -1);
1266 return size; 1270 return size;
1267 } 1271 }
1268 1272
1269 1273
1270 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1274 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1271 ExternalLabel* target_label, 1275 ExternalLabel* target_label,
1272 const ICData& ic_data, 1276 const ICData& ic_data,
1273 intptr_t argument_count, 1277 intptr_t argument_count,
1274 intptr_t deopt_id, 1278 intptr_t deopt_id,
1275 intptr_t token_pos, 1279 intptr_t token_pos,
1276 LocationSummary* locs) { 1280 LocationSummary* locs) {
1277 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1281 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1278 // Each ICData propagated from unoptimized to optimized code contains the 1282 // Each ICData propagated from unoptimized to optimized code contains the
1279 // function that corresponds to the Dart function of that IC call. Due 1283 // function that corresponds to the Dart function of that IC call. Due
1280 // to inlining in optimized code, that function may not correspond to the 1284 // to inlining in optimized code, that function may not correspond to the
1281 // top-level function (parsed_function().function()) which could be 1285 // top-level function (parsed_function().function()) which could be
1282 // reoptimized and which counter needs to be incremented. 1286 // reoptimized and which counter needs to be incremented.
1283 // Pass the function explicitly, it is used in IC stub. 1287 // Pass the function explicitly, it is used in IC stub.
1284 __ LoadObject(RDI, parsed_function().function()); 1288 __ LoadObject(RDI, parsed_function().function());
1285 __ LoadUniqueObject(RBX, ic_data); 1289 __ LoadUniqueObject(RBX, ic_data);
1286 GenerateDartCall(deopt_id, 1290 GenerateDartCall(deopt_id,
1287 token_pos, 1291 token_pos,
1288 target_label, 1292 target_label,
1289 RawPcDescriptors::kIcCall, 1293 RawPcDescriptors::kIcCall,
1290 locs); 1294 locs);
1291 __ Drop(argument_count, RCX); 1295 __ Drop(argument_count, RCX);
1292 } 1296 }
1293 1297
1294 1298
1295 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1299 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1296 const ICData& ic_data, 1300 const ICData& ic_data,
1297 intptr_t argument_count, 1301 intptr_t argument_count,
1298 intptr_t deopt_id, 1302 intptr_t deopt_id,
1299 intptr_t token_pos, 1303 intptr_t token_pos,
1300 LocationSummary* locs) { 1304 LocationSummary* locs) {
1301 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1305 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1302 __ LoadUniqueObject(RBX, ic_data); 1306 __ LoadUniqueObject(RBX, ic_data);
1303 GenerateDartCall(deopt_id, 1307 GenerateDartCall(deopt_id,
1304 token_pos, 1308 token_pos,
1305 target_label, 1309 target_label,
1306 RawPcDescriptors::kIcCall, 1310 RawPcDescriptors::kIcCall,
1307 locs); 1311 locs);
1308 __ Drop(argument_count, RCX); 1312 __ Drop(argument_count, RCX);
1309 } 1313 }
1310 1314
1311 1315
1312 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1316 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1313 const ICData& ic_data, 1317 const ICData& ic_data,
1314 intptr_t argument_count, 1318 intptr_t argument_count,
1315 intptr_t deopt_id, 1319 intptr_t deopt_id,
1316 intptr_t token_pos, 1320 intptr_t token_pos,
1317 LocationSummary* locs) { 1321 LocationSummary* locs) {
1318 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table(); 1322 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
1319 const String& name = String::Handle(ic_data.target_name()); 1323 const String& name = String::Handle(zone(), ic_data.target_name());
1320 const Array& arguments_descriptor = 1324 const Array& arguments_descriptor =
1321 Array::ZoneHandle(ic_data.arguments_descriptor()); 1325 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1322 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1326 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1323 const MegamorphicCache& cache = 1327 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1324 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor)); 1328 zone(), table->Lookup(name, arguments_descriptor));
1325 const Register receiverR = RDI; 1329 const Register receiverR = RDI;
1326 const Register cacheR = RBX; 1330 const Register cacheR = RBX;
1327 const Register targetR = RCX; 1331 const Register targetR = RCX;
1328 __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize)); 1332 __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize));
1329 __ LoadObject(cacheR, cache); 1333 __ LoadObject(cacheR, cache);
1330 1334
1331 if (FLAG_use_megamorphic_stub) { 1335 if (FLAG_use_megamorphic_stub) {
1332 __ call(&StubCode::MegamorphicLookupLabel()); 1336 __ call(&StubCode::MegamorphicLookupLabel());
1333 } else { 1337 } else {
1334 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1338 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 const Array& argument_names, 1479 const Array& argument_names,
1476 Label* failed, 1480 Label* failed,
1477 Label* match_found, 1481 Label* match_found,
1478 intptr_t deopt_id, 1482 intptr_t deopt_id,
1479 intptr_t token_index, 1483 intptr_t token_index,
1480 LocationSummary* locs) { 1484 LocationSummary* locs) {
1481 ASSERT(is_optimizing()); 1485 ASSERT(is_optimizing());
1482 1486
1483 __ Comment("EmitTestAndCall"); 1487 __ Comment("EmitTestAndCall");
1484 const Array& arguments_descriptor = 1488 const Array& arguments_descriptor =
1485 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1489 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1486 argument_names)); 1490 argument_names));
1487 // Load receiver into RAX. 1491 // Load receiver into RAX.
1488 __ movq(RAX, 1492 __ movq(RAX,
1489 Address(RSP, (argument_count - 1) * kWordSize)); 1493 Address(RSP, (argument_count - 1) * kWordSize));
1490 __ LoadObject(R10, arguments_descriptor); 1494 __ LoadObject(R10, arguments_descriptor);
1491 1495
1492 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid; 1496 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1493 const intptr_t kNumChecks = ic_data.NumberOfChecks(); 1497 const intptr_t kNumChecks = ic_data.NumberOfChecks();
1494 1498
1495 ASSERT(!ic_data.IsNull() && (kNumChecks > 0)); 1499 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1496 1500
1497 Label after_smi_test; 1501 Label after_smi_test;
1498 __ testq(RAX, Immediate(kSmiTagMask)); 1502 __ testq(RAX, Immediate(kSmiTagMask));
1499 if (kFirstCheckIsSmi) { 1503 if (kFirstCheckIsSmi) {
1500 // Jump if receiver is not Smi. 1504 // Jump if receiver is not Smi.
1501 if (kNumChecks == 1) { 1505 if (kNumChecks == 1) {
1502 __ j(NOT_ZERO, failed); 1506 __ j(NOT_ZERO, failed);
1503 } else { 1507 } else {
1504 __ j(NOT_ZERO, &after_smi_test); 1508 __ j(NOT_ZERO, &after_smi_test);
1505 } 1509 }
1506 // Do not use the code from the function, but let the code be patched so 1510 // Do not use the code from the function, but let the code be patched so
1507 // that we can record the outgoing edges to other code. 1511 // that we can record the outgoing edges to other code.
1508 GenerateDartCall(deopt_id, 1512 GenerateDartCall(deopt_id,
1509 token_index, 1513 token_index,
1510 &StubCode::CallStaticFunctionLabel(), 1514 &StubCode::CallStaticFunctionLabel(),
1511 RawPcDescriptors::kOther, 1515 RawPcDescriptors::kOther,
1512 locs); 1516 locs);
1513 const Function& function = Function::Handle(ic_data.GetTargetAt(0)); 1517 const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
1514 AddStaticCallTarget(function); 1518 AddStaticCallTarget(function);
1515 __ Drop(argument_count, RCX); 1519 __ Drop(argument_count, RCX);
1516 if (kNumChecks > 1) { 1520 if (kNumChecks > 1) {
1517 __ jmp(match_found); 1521 __ jmp(match_found);
1518 } 1522 }
1519 } else { 1523 } else {
1520 // Receiver is Smi, but Smi is not a valid class therefore fail. 1524 // Receiver is Smi, but Smi is not a valid class therefore fail.
1521 // (Smi class must be first in the list). 1525 // (Smi class must be first in the list).
1522 __ j(ZERO, failed); 1526 __ j(ZERO, failed);
1523 } 1527 }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 __ movups(reg, Address(RSP, 0)); 1797 __ movups(reg, Address(RSP, 0));
1794 __ AddImmediate(RSP, Immediate(kFpuRegisterSize)); 1798 __ AddImmediate(RSP, Immediate(kFpuRegisterSize));
1795 } 1799 }
1796 1800
1797 1801
1798 #undef __ 1802 #undef __
1799 1803
1800 } // namespace dart 1804 } // namespace dart
1801 1805
1802 #endif // defined TARGET_ARCH_X64 1806 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698