| 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/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/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 LocationSummary* locs = | 282 LocationSummary* locs = |
| 283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 284 locs->set_in(0, Location::RegisterLocation(RCX)); | 284 locs->set_in(0, Location::RegisterLocation(RCX)); |
| 285 locs->set_in(1, Location::RegisterLocation(RDX)); | 285 locs->set_in(1, Location::RegisterLocation(RDX)); |
| 286 locs->set_out(Location::RegisterLocation(RAX)); | 286 locs->set_out(Location::RegisterLocation(RAX)); |
| 287 return locs; | 287 return locs; |
| 288 } | 288 } |
| 289 | 289 |
| 290 | 290 |
| 291 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, | 291 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, |
| 292 EqualityCompareComp* comp) { | 292 intptr_t deopt_id, |
| 293 intptr_t token_pos, |
| 294 intptr_t try_index, |
| 295 Token::Kind kind, |
| 296 const LocationSummary& locs) { |
| 293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 297 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 294 comp->deopt_id(), | 298 deopt_id, |
| 295 comp->token_pos(), | 299 token_pos, |
| 296 comp->try_index()); | 300 try_index); |
| 297 const String& operator_name = String::ZoneHandle(Symbols::New("==")); | 301 const String& operator_name = String::ZoneHandle(Symbols::New("==")); |
| 298 const int kNumberOfArguments = 2; | 302 const int kNumberOfArguments = 2; |
| 299 const Array& kNoArgumentNames = Array::Handle(); | 303 const Array& kNoArgumentNames = Array::Handle(); |
| 300 const int kNumArgumentsChecked = 2; | 304 const int kNumArgumentsChecked = 2; |
| 301 | 305 |
| 302 Label done, false_label, true_label; | 306 Label done, false_label, true_label; |
| 303 Register left = comp->locs()->in(0).reg(); | 307 Register left = locs.in(0).reg(); |
| 304 Register right = comp->locs()->in(1).reg(); | 308 Register right = locs.in(1).reg(); |
| 305 __ popq(right); | 309 __ popq(right); |
| 306 __ popq(left); | 310 __ popq(left); |
| 307 const Immediate raw_null = | 311 const Immediate raw_null = |
| 308 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 312 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 309 Label check_identity, instance_call; | 313 Label check_identity, instance_call; |
| 310 __ cmpq(right, raw_null); | 314 __ cmpq(right, raw_null); |
| 311 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 315 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 312 __ cmpq(left, raw_null); | 316 __ cmpq(left, raw_null); |
| 313 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); | 317 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); |
| 314 | 318 |
| 315 __ Bind(&check_identity); | 319 __ Bind(&check_identity); |
| 316 __ cmpq(left, right); | 320 __ cmpq(left, right); |
| 317 __ j(EQUAL, &true_label); | 321 __ j(EQUAL, &true_label); |
| 318 if (comp->kind() == Token::kEQ) { | 322 if (kind == Token::kEQ) { |
| 319 __ LoadObject(RAX, compiler->bool_false()); | 323 __ LoadObject(RAX, compiler->bool_false()); |
| 320 __ jmp(&done); | 324 __ jmp(&done); |
| 321 __ Bind(&true_label); | 325 __ Bind(&true_label); |
| 322 __ LoadObject(RAX, compiler->bool_true()); | 326 __ LoadObject(RAX, compiler->bool_true()); |
| 323 __ jmp(&done); | 327 __ jmp(&done); |
| 324 } else { | 328 } else { |
| 325 ASSERT(comp->kind() == Token::kNE); | 329 ASSERT(kind == Token::kNE); |
| 326 __ jmp(&false_label); | 330 __ jmp(&false_label); |
| 327 } | 331 } |
| 328 | 332 |
| 329 __ Bind(&instance_call); | 333 __ Bind(&instance_call); |
| 330 __ pushq(left); | 334 __ pushq(left); |
| 331 __ pushq(right); | 335 __ pushq(right); |
| 332 compiler->GenerateInstanceCall(comp->deopt_id(), | 336 compiler->GenerateInstanceCall(deopt_id, |
| 333 comp->token_pos(), | 337 token_pos, |
| 334 comp->try_index(), | 338 try_index, |
| 335 operator_name, | 339 operator_name, |
| 336 kNumberOfArguments, | 340 kNumberOfArguments, |
| 337 kNoArgumentNames, | 341 kNoArgumentNames, |
| 338 kNumArgumentsChecked, | 342 kNumArgumentsChecked, |
| 339 comp->locs()->stack_bitmap()); | 343 locs.stack_bitmap()); |
| 340 ASSERT(comp->locs()->out().reg() == RAX); | 344 if (kind == Token::kNE) { |
| 341 if (comp->kind() == Token::kNE) { | |
| 342 // Negate the condition: true label returns false and vice versa. | 345 // Negate the condition: true label returns false and vice versa. |
| 343 __ CompareObject(RAX, compiler->bool_true()); | 346 __ CompareObject(RAX, compiler->bool_true()); |
| 344 __ j(EQUAL, &true_label, Assembler::kNearJump); | 347 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 345 __ Bind(&false_label); | 348 __ Bind(&false_label); |
| 346 __ LoadObject(RAX, compiler->bool_true()); | 349 __ LoadObject(RAX, compiler->bool_true()); |
| 347 __ jmp(&done, Assembler::kNearJump); | 350 __ jmp(&done, Assembler::kNearJump); |
| 348 __ Bind(&true_label); | 351 __ Bind(&true_label); |
| 349 __ LoadObject(RAX, compiler->bool_false()); | 352 __ LoadObject(RAX, compiler->bool_false()); |
| 350 } | 353 } |
| 351 __ Bind(&done); | 354 __ Bind(&done); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 return; | 664 return; |
| 662 } | 665 } |
| 663 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 666 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 664 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), | 667 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), |
| 665 deopt_id(), token_pos(), try_index()); | 668 deopt_id(), token_pos(), try_index()); |
| 666 } else { | 669 } else { |
| 667 Register left = locs()->in(0).reg(); | 670 Register left = locs()->in(0).reg(); |
| 668 Register right = locs()->in(1).reg(); | 671 Register right = locs()->in(1).reg(); |
| 669 __ pushq(left); | 672 __ pushq(left); |
| 670 __ pushq(right); | 673 __ pushq(right); |
| 671 EmitEqualityAsInstanceCall(compiler, this); | 674 EmitEqualityAsInstanceCall(compiler, |
| 675 deopt_id(), |
| 676 token_pos(), |
| 677 try_index(), |
| 678 kind(), |
| 679 *locs()); |
| 680 ASSERT(locs()->out().reg() == RAX); |
| 672 } | 681 } |
| 673 } | 682 } |
| 674 | 683 |
| 675 | 684 |
| 676 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 685 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 677 const intptr_t kNumInputs = 2; | 686 const intptr_t kNumInputs = 2; |
| 678 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { | 687 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { |
| 679 const intptr_t kNumTemps = 1; | 688 const intptr_t kNumTemps = 1; |
| 680 LocationSummary* summary = | 689 LocationSummary* summary = |
| 681 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2157 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), | 2166 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), |
| 2158 deopt_id(), token_pos(), try_index()); | 2167 deopt_id(), token_pos(), try_index()); |
| 2159 return; | 2168 return; |
| 2160 } | 2169 } |
| 2161 // Otherwise polymorphic dispatch? | 2170 // Otherwise polymorphic dispatch? |
| 2162 } | 2171 } |
| 2163 Register left = locs()->in(0).reg(); | 2172 Register left = locs()->in(0).reg(); |
| 2164 Register right = locs()->in(1).reg(); | 2173 Register right = locs()->in(1).reg(); |
| 2165 __ pushq(left); | 2174 __ pushq(left); |
| 2166 __ pushq(right); | 2175 __ pushq(right); |
| 2167 // Not equal is always split into '==' and negate, | 2176 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) { |
| 2177 EmitEqualityAsInstanceCall(compiler, |
| 2178 deopt_id(), |
| 2179 token_pos(), |
| 2180 try_index(), |
| 2181 Token::kEQ, // kNE reverse occurs at branch. |
| 2182 *locs()); |
| 2183 } else { |
| 2184 const String& function_name = |
| 2185 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 2186 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 2187 deopt_id(), |
| 2188 token_pos(), |
| 2189 try_index()); |
| 2190 const intptr_t kNumArguments = 2; |
| 2191 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 2192 compiler->GenerateInstanceCall(deopt_id(), |
| 2193 token_pos(), |
| 2194 try_index(), |
| 2195 function_name, |
| 2196 kNumArguments, |
| 2197 Array::ZoneHandle(), // No optional args. |
| 2198 kNumArgsChecked, |
| 2199 locs()->stack_bitmap()); |
| 2200 } |
| 2168 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 2201 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 2169 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind(); | |
| 2170 const String& function_name = | |
| 2171 String::ZoneHandle(Symbols::New(Token::Str(call_kind))); | |
| 2172 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 2173 deopt_id(), | |
| 2174 token_pos(), | |
| 2175 try_index()); | |
| 2176 const intptr_t kNumArguments = 2; | |
| 2177 const intptr_t kNumArgsChecked = 2; // Type-feedback. | |
| 2178 compiler->GenerateInstanceCall(deopt_id(), | |
| 2179 token_pos(), | |
| 2180 try_index(), | |
| 2181 function_name, | |
| 2182 kNumArguments, | |
| 2183 Array::ZoneHandle(), // No optional arguments. | |
| 2184 kNumArgsChecked, | |
| 2185 locs()->stack_bitmap()); | |
| 2186 __ CompareObject(RAX, compiler->bool_true()); | 2202 __ CompareObject(RAX, compiler->bool_true()); |
| 2187 EmitBranchOnCondition(compiler, branch_condition); | 2203 EmitBranchOnCondition(compiler, branch_condition); |
| 2188 } | 2204 } |
| 2189 | 2205 |
| 2190 } // namespace dart | 2206 } // namespace dart |
| 2191 | 2207 |
| 2192 #undef __ | 2208 #undef __ |
| 2193 | 2209 |
| 2194 #endif // defined TARGET_ARCH_X64 | 2210 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |