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

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

Issue 10536086: Add stack check in loops so that loops can be stopped. Optimize relational operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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/intermediate_language_ia32.cc ('k') | no next file » | 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/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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 token_index(), 235 token_index(),
236 try_index(), 236 try_index(),
237 operator_name, 237 operator_name,
238 kNumberOfArguments, 238 kNumberOfArguments,
239 kNoArgumentNames, 239 kNoArgumentNames,
240 kNumArgumentsChecked); 240 kNumArgumentsChecked);
241 __ Bind(&done); 241 __ Bind(&done);
242 } 242 }
243 243
244 244
245 static Condition TokenKindToSmiCondition(Token::Kind kind) {
246 switch (kind) {
247 case Token::kEQ: return EQUAL;
248 case Token::kNE: return NOT_EQUAL;
249 case Token::kLT: return LESS;
250 case Token::kGT: return GREATER;
251 case Token::kLTE: return LESS_EQUAL;
252 case Token::kGTE: return GREATER_EQUAL;
253 default:
254 UNREACHABLE();
255 return OVERFLOW;
256 }
257 }
258
259
260 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
261 RelationalOpComp* comp) {
262 Register left = comp->locs()->in(0).reg();
263 Register right = comp->locs()->in(1).reg();
264 Register result = comp->locs()->out().reg();
265 Label* deopt = compiler->AddDeoptStub(comp->cid(),
266 comp->token_index(),
267 comp->try_index(),
268 kDeoptSmiCompareSmis,
269 left,
270 right);
271 __ movq(TMP, left);
272 __ orq(TMP, right);
273 __ testq(TMP, Immediate(kSmiTagMask));
274 __ j(NOT_ZERO, deopt);
275 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
276 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
277 Condition condition = TokenKindToSmiCondition(comp->kind());
278
279 Label done, is_true;
280 __ cmpq(left, right);
281 __ j(condition, &is_true);
282 __ LoadObject(result, bool_false);
283 __ jmp(&done);
284 __ Bind(&is_true);
285 __ LoadObject(result, bool_true);
286 __ Bind(&done);
287 }
288
289
290 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
291 if (operands_class_id() == kSmi) {
292 const intptr_t kNumInputs = 2;
293 const intptr_t kNumTemps = 0;
294 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
295 summary->set_in(0, Location::RequiresRegister());
296 summary->set_in(1, Location::RequiresRegister());
297 summary->set_out(Location::RequiresRegister());
298 return summary;
299 }
300 if (operands_class_id() == kDouble) {
301 const intptr_t kNumInputs = 2;
302 const intptr_t kNumTemps = 1;
303 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
304 summary->set_in(0, Location::RequiresRegister());
305 summary->set_in(1, Location::RequiresRegister());
306 summary->set_out(Location::RequiresRegister());
307 summary->set_temp(0, Location::RequiresRegister());
308 return summary;
309 }
310 ASSERT(operands_class_id() == kObject);
311 return MakeCallSummary();
312 }
313
314
315
316 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
317 switch (kind) {
318 case Token::kEQ: return EQUAL;
319 case Token::kLT: return BELOW;
320 case Token::kGT: return ABOVE;
321 case Token::kLTE: return BELOW_EQUAL;
322 default:
323 UNREACHABLE();
324 return OVERFLOW;
325 }
326 }
327
328
329 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
330 RelationalOpComp* comp) {
331 Register left = comp->locs()->in(0).reg();
332 Register right = comp->locs()->in(1).reg();
333 Register result = comp->locs()->out().reg();
334 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
335 Register temp = comp->locs()->temp(0).reg();
336 Label* deopt = compiler->AddDeoptStub(comp->cid(),
337 comp->token_index(),
338 comp->try_index(),
339 kDeoptDoubleComparison,
340 left,
341 right);
342 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
343 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
344 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
345 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
346 Condition true_condition = TokenKindToDoubleCondition(comp->kind());
347 Label is_false, is_true, done;
348 __ comisd(XMM0, XMM1);
349 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
350 __ j(true_condition, &is_true, Assembler::kNearJump);
351 __ Bind(&is_false);
352 __ LoadObject(result, bool_false);
353 __ jmp(&done);
354 __ Bind(&is_true);
355 __ LoadObject(result, bool_true);
356 __ Bind(&done);
357 }
358
359
360 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
361 if (operands_class_id() == kSmi) {
362 EmitSmiRelationalOp(compiler, this);
363 return;
364 }
365 if (operands_class_id() == kDouble) {
366 EmitDoubleRelationalOp(compiler, this);
367 return;
368 }
369 const String& function_name =
370 String::ZoneHandle(String::NewSymbol(Token::Str(kind())));
371 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
372 cid(),
373 token_index(),
374 try_index());
375 const intptr_t kNumArguments = 2;
376 const intptr_t kNumArgsChecked = 2; // Type-feedback.
377 compiler->GenerateInstanceCall(cid(),
378 token_index(),
379 try_index(),
380 function_name,
381 kNumArguments,
382 Array::ZoneHandle(), // No optional arguments.
383 kNumArgsChecked);
384 ASSERT(locs()->out().reg() == RAX);
385 }
386
387
245 LocationSummary* NativeCallComp::MakeLocationSummary() const { 388 LocationSummary* NativeCallComp::MakeLocationSummary() const {
246 LocationSummary* locs = new LocationSummary(0, 3); 389 LocationSummary* locs = new LocationSummary(0, 3);
247 locs->set_temp(0, Location::RegisterLocation(RAX)); 390 locs->set_temp(0, Location::RegisterLocation(RAX));
248 locs->set_temp(1, Location::RegisterLocation(RBX)); 391 locs->set_temp(1, Location::RegisterLocation(RBX));
249 locs->set_temp(2, Location::RegisterLocation(R10)); 392 locs->set_temp(2, Location::RegisterLocation(R10));
250 locs->set_out(Location::RequiresRegister()); 393 locs->set_out(Location::RequiresRegister());
251 return locs; 394 return locs;
252 } 395 }
253 396
254 397
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 1000
858 ASSERT(!exception_var().is_captured()); 1001 ASSERT(!exception_var().is_captured());
859 ASSERT(!stacktrace_var().is_captured()); 1002 ASSERT(!stacktrace_var().is_captured());
860 __ movq(Address(RBP, exception_var().index() * kWordSize), 1003 __ movq(Address(RBP, exception_var().index() * kWordSize),
861 kExceptionObjectReg); 1004 kExceptionObjectReg);
862 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), 1005 __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
863 kStackTraceObjectReg); 1006 kStackTraceObjectReg);
864 } 1007 }
865 1008
866 1009
1010 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
1011 return LocationSummary::Make(0, Location::NoLocation());
1012 }
1013
1014
1015 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1016 // Generate stack overflow check.
1017 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
Vyacheslav Egorov (Google) 2012/06/11 12:51:21 I though we can use TMP only in the assembler itse
srdjan 2012/06/11 16:00:50 Yes, unfortunately, we are using TMP outside in se
1018 __ cmpq(RSP, Address(TMP, 0));
1019 Label no_stack_overflow;
1020 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1021 compiler->GenerateCallRuntime(cid(),
1022 token_index(),
1023 try_index(),
1024 kStackOverflowRuntimeEntry);
1025 __ Bind(&no_stack_overflow);
1026 }
1027
1028
867 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1029 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
868 const intptr_t kNumInputs = 2; 1030 const intptr_t kNumInputs = 2;
869 1031
870 if (operands_type() == kDoubleOperands) { 1032 if (operands_type() == kDoubleOperands) {
871 const intptr_t kNumTemps = 1; 1033 const intptr_t kNumTemps = 1;
872 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1034 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
873 summary->set_in(0, Location::RequiresRegister()); 1035 summary->set_in(0, Location::RequiresRegister());
874 summary->set_in(1, Location::RequiresRegister()); 1036 summary->set_in(1, Location::RequiresRegister());
875 summary->set_out(Location::RegisterLocation(RAX)); 1037 summary->set_out(Location::RegisterLocation(RAX));
876 summary->set_temp(0, Location::RequiresRegister()); 1038 summary->set_temp(0, Location::RequiresRegister());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 } else { 1383 } else {
1222 UNREACHABLE(); 1384 UNREACHABLE();
1223 } 1385 }
1224 } 1386 }
1225 1387
1226 } // namespace dart 1388 } // namespace dart
1227 1389
1228 #undef __ 1390 #undef __
1229 1391
1230 #endif // defined TARGET_ARCH_X64 1392 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698