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

Side by Side Diff: src/x64/codegen-x64.cc

Issue 141030: X64 implementation: if-then-else (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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 | « src/x64/assembler-x64.cc ('k') | src/x64/jump-target-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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 96
97 #define __ ACCESS_MASM(masm_) 97 #define __ ACCESS_MASM(masm_)
98 98
99 99
100 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { 100 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) {
101 UNIMPLEMENTED(); 101 UNIMPLEMENTED();
102 } 102 }
103 103
104 void CodeGenerator::TestCodeGenerator() { 104 void CodeGenerator::TestCodeGenerator() {
105 // Compile a function from a string, and run it. 105 // Compile a function from a string, and run it.
106
107 // Set flags appropriately for this stage of implementation.
108 // TODO(X64): Make ic and lazy compilation work, and stop disabling them.
109 // These settings stick - remove them when we don't want them anymore.
110 #ifdef DEBUG
111 FLAG_print_builtin_source = true;
112 FLAG_print_builtin_ast = true;
113 #endif
114 FLAG_use_ic = false;
115 FLAG_lazy = false;
116
106 Handle<JSFunction> test_function = Compiler::Compile( 117 Handle<JSFunction> test_function = Compiler::Compile(
107 Factory::NewStringFromAscii(CStrVector( 118 Factory::NewStringFromAscii(CStrVector(
108 "39;" 119 "// Put all code in anonymous function to avoid global scope.\n"
109 "(function(){" 120 "(function(){"
110 "function foo(x, y){var w; y = x; x = w; w = y; y = x; return w;};" 121 " function test_if_then_else(x, y, z){"
111 "function bar(x, y, zee){return zee;};" 122 " if (x) {"
112 "foo(2,3);" 123 " x = y;"
113 "return foo(bar(foo(1,3), 42, 47), foo( -25.3, 2));" 124 " } else {"
125 " x = z;"
126 " }"
127 " return x;"
128 " }"
129 " function test_local_variables(x, y){"
130 " var w; y = x; x = w; w = y; y = x; return w;"
131 " };"
132 " test_local_variables(2,3);"
133 " function test_nesting_calls(x, y, zee){return zee;};"
134 " test_local_variables("
135 " test_nesting_calls(test_local_variables(1,3), 42, 47),"
136 " test_local_variables(-25.3, 2));"
137 " return test_if_then_else(1, 47, 39);"
114 "})()")), 138 "})()")),
115 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), 139 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")),
116 0, 140 0,
117 0, 141 0,
118 NULL, 142 NULL,
119 NULL); 143 NULL);
120 144
121 Code* code_object = test_function->code(); // Local for debugging ease. 145 Code* code_object = test_function->code(); // Local for debugging ease.
122 USE(code_object); 146 USE(code_object);
123 147
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 Load(expression); 434 Load(expression);
411 // Remove the lingering expression result from the top of stack. 435 // Remove the lingering expression result from the top of stack.
412 frame_->Drop(); 436 frame_->Drop();
413 } 437 }
414 438
415 439
416 void CodeGenerator::VisitEmptyStatement(EmptyStatement* a) { 440 void CodeGenerator::VisitEmptyStatement(EmptyStatement* a) {
417 UNIMPLEMENTED(); 441 UNIMPLEMENTED();
418 } 442 }
419 443
420 void CodeGenerator::VisitIfStatement(IfStatement* a) { 444
421 UNIMPLEMENTED(); 445 void CodeGenerator::VisitIfStatement(IfStatement* node) {
446 ASSERT(!in_spilled_code());
447 Comment cmnt(masm_, "[ IfStatement");
448 // Generate different code depending on which parts of the if statement
449 // are present or not.
450 bool has_then_stm = node->HasThenStatement();
451 bool has_else_stm = node->HasElseStatement();
452
453 CodeForStatementPosition(node);
454 JumpTarget exit;
455 if (has_then_stm && has_else_stm) {
456 JumpTarget then;
457 JumpTarget else_;
458 ControlDestination dest(&then, &else_, true);
459 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &dest, true);
460
461 if (dest.false_was_fall_through()) {
462 // The else target was bound, so we compile the else part first.
463 Visit(node->else_statement());
464
465 // We may have dangling jumps to the then part.
466 if (then.is_linked()) {
467 if (has_valid_frame()) exit.Jump();
468 then.Bind();
469 Visit(node->then_statement());
470 }
471 } else {
472 // The then target was bound, so we compile the then part first.
473 Visit(node->then_statement());
474
475 if (else_.is_linked()) {
476 if (has_valid_frame()) exit.Jump();
477 else_.Bind();
478 Visit(node->else_statement());
479 }
480 }
481
482 } else if (has_then_stm) {
483 ASSERT(!has_else_stm);
484 JumpTarget then;
485 ControlDestination dest(&then, &exit, true);
486 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &dest, true);
487
488 if (dest.false_was_fall_through()) {
489 // The exit label was bound. We may have dangling jumps to the
490 // then part.
491 if (then.is_linked()) {
492 exit.Unuse();
493 exit.Jump();
494 then.Bind();
495 Visit(node->then_statement());
496 }
497 } else {
498 // The then label was bound.
499 Visit(node->then_statement());
500 }
501
502 } else if (has_else_stm) {
503 ASSERT(!has_then_stm);
504 JumpTarget else_;
505 ControlDestination dest(&exit, &else_, false);
506 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &dest, true);
507
508 if (dest.true_was_fall_through()) {
509 // The exit label was bound. We may have dangling jumps to the
510 // else part.
511 if (else_.is_linked()) {
512 exit.Unuse();
513 exit.Jump();
514 else_.Bind();
515 Visit(node->else_statement());
516 }
517 } else {
518 // The else label was bound.
519 Visit(node->else_statement());
520 }
521
522 } else {
523 ASSERT(!has_then_stm && !has_else_stm);
524 // We only care about the condition's side effects (not its value
525 // or control flow effect). LoadCondition is called without
526 // forcing control flow.
527 ControlDestination dest(&exit, &exit, true);
528 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &dest, false);
529 if (!dest.is_used()) {
530 // We got a value on the frame rather than (or in addition to)
531 // control flow.
532 frame_->Drop();
533 }
534 }
535
536 if (exit.is_linked()) {
537 exit.Bind();
538 }
422 } 539 }
423 540
541
424 void CodeGenerator::VisitContinueStatement(ContinueStatement* a) { 542 void CodeGenerator::VisitContinueStatement(ContinueStatement* a) {
425 UNIMPLEMENTED(); 543 UNIMPLEMENTED();
426 } 544 }
427 545
428 void CodeGenerator::VisitBreakStatement(BreakStatement* a) { 546 void CodeGenerator::VisitBreakStatement(BreakStatement* a) {
429 UNIMPLEMENTED(); 547 UNIMPLEMENTED();
430 } 548 }
431 549
432 550
433 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 551 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 if (HasStackOverflow() && 1104 if (HasStackOverflow() &&
987 !dest->is_used() && 1105 !dest->is_used() &&
988 frame_->height() == original_height) { 1106 frame_->height() == original_height) {
989 dest->Goto(true); 1107 dest->Goto(true);
990 } 1108 }
991 } 1109 }
992 1110
993 if (force_control && !dest->is_used()) { 1111 if (force_control && !dest->is_used()) {
994 // Convert the TOS value into flow to the control destination. 1112 // Convert the TOS value into flow to the control destination.
995 // TODO(X64): Make control flow to control destinations work. 1113 // TODO(X64): Make control flow to control destinations work.
996 // ToBoolean(dest); 1114 ToBoolean(dest);
997 } 1115 }
998 1116
999 ASSERT(!(force_control && !dest->is_used())); 1117 ASSERT(!(force_control && !dest->is_used()));
1000 ASSERT(dest->is_used() || frame_->height() == original_height + 1); 1118 ASSERT(dest->is_used() || frame_->height() == original_height + 1);
1001 } 1119 }
1002 1120
1003 1121
1122 class ToBooleanStub: public CodeStub {
1123 public:
1124 ToBooleanStub() { }
1125
1126 void Generate(MacroAssembler* masm);
1127
1128 private:
1129 Major MajorKey() { return ToBoolean; }
1130 int MinorKey() { return 0; }
1131 };
1132
1133
1134 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and
1135 // convert it to a boolean in the condition code register or jump to
1136 // 'false_target'/'true_target' as appropriate.
1137 void CodeGenerator::ToBoolean(ControlDestination* dest) {
1138 Comment cmnt(masm_, "[ ToBoolean");
1139
1140 // The value to convert should be popped from the frame.
1141 Result value = frame_->Pop();
1142 value.ToRegister();
1143 // Fast case checks.
1144
1145 // 'false' => false.
1146 __ movq(kScratchRegister, Factory::false_value(), RelocInfo::EMBEDDED_OBJECT);
1147 __ cmpq(value.reg(), kScratchRegister);
1148 dest->false_target()->Branch(equal);
1149
1150 // 'true' => true.
1151 __ movq(kScratchRegister, Factory::true_value(), RelocInfo::EMBEDDED_OBJECT);
1152 __ cmpq(value.reg(), kScratchRegister);
1153 dest->true_target()->Branch(equal);
1154
1155 // 'undefined' => false.
1156 __ movq(kScratchRegister,
1157 Factory::undefined_value(),
1158 RelocInfo::EMBEDDED_OBJECT);
1159 __ cmpq(value.reg(), kScratchRegister);
1160 dest->false_target()->Branch(equal);
1161
1162 // Smi => false iff zero.
1163 ASSERT(kSmiTag == 0);
1164 __ testq(value.reg(), value.reg());
1165 dest->false_target()->Branch(zero);
1166 __ testq(value.reg(), Immediate(kSmiTagMask));
1167 dest->true_target()->Branch(zero);
1168
1169 // Call the stub for all other cases.
1170 frame_->Push(&value); // Undo the Pop() from above.
1171 ToBooleanStub stub;
1172 Result temp = frame_->CallStub(&stub, 1);
1173 // Convert the result to a condition code.
1174 __ testq(temp.reg(), temp.reg());
1175 temp.Unuse();
1176 dest->Split(not_equal);
1177 }
1178
1179
1004 void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) { 1180 void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) {
1005 UNIMPLEMENTED(); 1181 UNIMPLEMENTED();
1006 // TODO(X64): Implement security policy for loads of smis. 1182 // TODO(X64): Implement security policy for loads of smis.
1007 } 1183 }
1008 1184
1009 1185
1010 bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) { 1186 bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) {
1011 return false; 1187 return false;
1012 } 1188 }
1013 1189
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 #undef __ 1695 #undef __
1520 1696
1521 // End of CodeGenerator implementation. 1697 // End of CodeGenerator implementation.
1522 1698
1523 // ----------------------------------------------------------------------------- 1699 // -----------------------------------------------------------------------------
1524 // Implementation of stubs. 1700 // Implementation of stubs.
1525 1701
1526 // Stub classes have public member named masm, not masm_. 1702 // Stub classes have public member named masm, not masm_.
1527 #define __ ACCESS_MASM(masm) 1703 #define __ ACCESS_MASM(masm)
1528 1704
1529 class ToBooleanStub: public CodeStub {
1530 public:
1531 ToBooleanStub() { }
1532
1533 void Generate(MacroAssembler* masm);
1534
1535 private:
1536 Major MajorKey() { return ToBoolean; }
1537 int MinorKey() { return 0; }
1538 };
1539
1540
1541 void ToBooleanStub::Generate(MacroAssembler* masm) { 1705 void ToBooleanStub::Generate(MacroAssembler* masm) {
1542 Label false_result, true_result, not_string; 1706 Label false_result, true_result, not_string;
1543 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 1707 __ movq(rax, Operand(rsp, 1 * kPointerSize));
1544 1708
1545 // 'null' => false. 1709 // 'null' => false.
1546 __ movq(kScratchRegister, Factory::null_value(), RelocInfo::EMBEDDED_OBJECT); 1710 __ movq(kScratchRegister, Factory::null_value(), RelocInfo::EMBEDDED_OBJECT);
1547 __ cmpq(rax, kScratchRegister); 1711 __ cmpq(rax, kScratchRegister);
1548 __ j(equal, &false_result); 1712 __ j(equal, &false_result);
1549 1713
1550 // Get the map and type of the heap object. 1714 // Get the map and type of the heap object.
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers 2555 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers
2392 2556
2393 // Restore frame pointer and return. 2557 // Restore frame pointer and return.
2394 __ pop(rbp); 2558 __ pop(rbp);
2395 __ ret(0); 2559 __ ret(0);
2396 } 2560 }
2397 2561
2398 #undef __ 2562 #undef __
2399 2563
2400 } } // namespace v8::internal 2564 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/jump-target-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698