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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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.cc ('k') | runtime/vm/intermediate_language_x64.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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 token_index(), 225 token_index(),
226 try_index(), 226 try_index(),
227 operator_name, 227 operator_name,
228 kNumberOfArguments, 228 kNumberOfArguments,
229 kNoArgumentNames, 229 kNoArgumentNames,
230 kNumArgumentsChecked); 230 kNumArgumentsChecked);
231 __ Bind(&done); 231 __ Bind(&done);
232 } 232 }
233 233
234 234
235 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
236 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) {
237 const intptr_t kNumInputs = 2;
238 const intptr_t kNumTemps = 1;
239 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
240 summary->set_in(0, Location::RequiresRegister());
241 summary->set_in(1, Location::RequiresRegister());
242 summary->set_out(Location::RequiresRegister());
243 summary->set_temp(0, Location::RequiresRegister());
244 return summary;
245 }
246 ASSERT(operands_class_id() == kObject);
247 return MakeCallSummary();
248 }
249
250
251 static Condition TokenKindToSmiCondition(Token::Kind kind) {
252 switch (kind) {
253 case Token::kEQ: return EQUAL;
254 case Token::kNE: return NOT_EQUAL;
255 case Token::kLT: return LESS;
256 case Token::kGT: return GREATER;
257 case Token::kLTE: return LESS_EQUAL;
258 case Token::kGTE: return GREATER_EQUAL;
259 default:
260 UNREACHABLE();
261 return OVERFLOW;
262 }
263 }
264
265
266 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
267 RelationalOpComp* comp) {
268 Register left = comp->locs()->in(0).reg();
269 Register right = comp->locs()->in(1).reg();
270 Register result = comp->locs()->out().reg();
271 Register temp = comp->locs()->temp(0).reg();
272 Label* deopt = compiler->AddDeoptStub(comp->cid(),
273 comp->token_index(),
274 comp->try_index(),
275 kDeoptSmiCompareSmis,
276 left,
277 right);
278 __ movl(temp, left);
279 __ orl(temp, right);
280 __ testl(temp, Immediate(kSmiTagMask));
281 __ j(NOT_ZERO, deopt);
282 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
283 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
284 Condition condition = TokenKindToSmiCondition(comp->kind());
285
286 Label done, is_true;
287 __ cmpl(left, right);
288 __ j(condition, &is_true);
289 __ LoadObject(result, bool_false);
290 __ jmp(&done);
291 __ Bind(&is_true);
292 __ LoadObject(result, bool_true);
293 __ Bind(&done);
294 }
295
296
297 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
298 switch (kind) {
299 case Token::kEQ: return EQUAL;
300 case Token::kLT: return BELOW;
301 case Token::kGT: return ABOVE;
302 case Token::kLTE: return BELOW_EQUAL;
303 default:
304 UNREACHABLE();
305 return OVERFLOW;
306 }
307 }
308
309
310 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
311 RelationalOpComp* comp) {
312 Register left = comp->locs()->in(0).reg();
313 Register right = comp->locs()->in(1).reg();
314 Register result = comp->locs()->out().reg();
315 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
316 Register temp = comp->locs()->temp(0).reg();
317 Label* deopt = compiler->AddDeoptStub(comp->cid(),
318 comp->token_index(),
319 comp->try_index(),
320 kDeoptDoubleComparison,
321 left,
322 right);
323 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
324 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
325 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
326 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
327 Condition true_condition = TokenKindToDoubleCondition(comp->kind());
328 Label is_false, is_true, done;
329 __ comisd(XMM0, XMM1);
330 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
331 __ j(true_condition, &is_true, Assembler::kNearJump);
332 __ Bind(&is_false);
333 __ LoadObject(result, bool_false);
334 __ jmp(&done);
335 __ Bind(&is_true);
336 __ LoadObject(result, bool_true);
337 __ Bind(&done);
338 }
339
340
341
342 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
343 if (operands_class_id() == kSmi) {
344 EmitSmiRelationalOp(compiler, this);
345 return;
346 }
347 if (operands_class_id() == kDouble) {
348 EmitDoubleRelationalOp(compiler, this);
349 return;
350 }
351 const String& function_name =
352 String::ZoneHandle(String::NewSymbol(Token::Str(kind())));
353 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
354 cid(),
355 token_index(),
356 try_index());
357 const intptr_t kNumArguments = 2;
358 const intptr_t kNumArgsChecked = 2; // Type-feedback.
359 compiler->GenerateInstanceCall(cid(),
360 token_index(),
361 try_index(),
362 function_name,
363 kNumArguments,
364 Array::ZoneHandle(), // No optional arguments.
365 kNumArgsChecked);
366 ASSERT(locs()->out().reg() == EAX);
367 }
368
369
235 LocationSummary* NativeCallComp::MakeLocationSummary() const { 370 LocationSummary* NativeCallComp::MakeLocationSummary() const {
236 LocationSummary* locs = new LocationSummary(0, 3); 371 LocationSummary* locs = new LocationSummary(0, 3);
237 locs->set_temp(0, Location::RegisterLocation(EAX)); 372 locs->set_temp(0, Location::RegisterLocation(EAX));
238 locs->set_temp(1, Location::RegisterLocation(ECX)); 373 locs->set_temp(1, Location::RegisterLocation(ECX));
239 locs->set_temp(2, Location::RegisterLocation(EDX)); 374 locs->set_temp(2, Location::RegisterLocation(EDX));
240 locs->set_out(Location::RequiresRegister()); 375 locs->set_out(Location::RequiresRegister());
241 return locs; 376 return locs;
242 } 377 }
243 378
244 379
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 900
766 ASSERT(!exception_var().is_captured()); 901 ASSERT(!exception_var().is_captured());
767 ASSERT(!stacktrace_var().is_captured()); 902 ASSERT(!stacktrace_var().is_captured());
768 __ movl(Address(EBP, exception_var().index() * kWordSize), 903 __ movl(Address(EBP, exception_var().index() * kWordSize),
769 kExceptionObjectReg); 904 kExceptionObjectReg);
770 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 905 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
771 kStackTraceObjectReg); 906 kStackTraceObjectReg);
772 } 907 }
773 908
774 909
910 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
911 return LocationSummary::Make(0, Location::NoLocation());
912 }
913
914
915 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
916 __ cmpl(ESP,
917 Address::Absolute(Isolate::Current()->stack_limit_address()));
918 Label no_stack_overflow;
919 __ j(ABOVE, &no_stack_overflow);
920 compiler->GenerateCallRuntime(cid(),
921 token_index(),
922 try_index(),
923 kStackOverflowRuntimeEntry);
924 __ Bind(&no_stack_overflow);
925 }
926
927
775 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 928 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
776 const intptr_t kNumInputs = 2; 929 const intptr_t kNumInputs = 2;
777 const intptr_t kNumTemps = 0; 930 const intptr_t kNumTemps = 0;
778 if (operands_type() == kDoubleOperands) { 931 if (operands_type() == kDoubleOperands) {
779 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 932 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
780 summary->set_in(0, Location::RequiresRegister()); 933 summary->set_in(0, Location::RequiresRegister());
781 summary->set_in(1, Location::RequiresRegister()); 934 summary->set_in(1, Location::RequiresRegister());
782 summary->set_out(Location::SameAsFirstInput()); 935 summary->set_out(Location::SameAsFirstInput());
783 return summary; 936 return summary;
784 } 937 }
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 UNREACHABLE(); 1247 UNREACHABLE();
1095 } 1248 }
1096 } 1249 }
1097 1250
1098 1251
1099 } // namespace dart 1252 } // namespace dart
1100 1253
1101 #undef __ 1254 #undef __
1102 1255
1103 #endif // defined TARGET_ARCH_X64 1256 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698