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

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 3166033: Improve the code generated by the full codegen by keeping... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 3 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/full-codegen.cc ('k') | src/x64/full-codegen-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 break; 239 break;
240 case kStack: 240 case kStack:
241 __ push(reg); 241 __ push(reg);
242 break; 242 break;
243 } 243 }
244 break; 244 break;
245 245
246 case Expression::kTest: 246 case Expression::kTest:
247 // For simplicity we always test the accumulator register. 247 // For simplicity we always test the accumulator register.
248 if (!reg.is(result_register())) __ mov(result_register(), reg); 248 if (!reg.is(result_register())) __ mov(result_register(), reg);
249 DoTest(true_label_, false_label_, NULL); 249 DoTest(true_label_, false_label_, fall_through_);
250 break; 250 break;
251 } 251 }
252 } 252 }
253 253
254 254
255 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) { 255 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
256 switch (context) { 256 switch (context) {
257 case Expression::kUninitialized: 257 case Expression::kUninitialized:
258 UNREACHABLE(); 258 UNREACHABLE();
259 case Expression::kEffect: 259 case Expression::kEffect:
260 // Nothing to do. 260 // Nothing to do.
261 break; 261 break;
262 case Expression::kValue: { 262 case Expression::kValue: {
263 MemOperand slot_operand = EmitSlotSearch(slot, result_register()); 263 MemOperand slot_operand = EmitSlotSearch(slot, result_register());
264 switch (location_) { 264 switch (location_) {
265 case kAccumulator: 265 case kAccumulator:
266 __ mov(result_register(), slot_operand); 266 __ mov(result_register(), slot_operand);
267 break; 267 break;
268 case kStack: 268 case kStack:
269 // Memory operands can be pushed directly. 269 // Memory operands can be pushed directly.
270 __ push(slot_operand); 270 __ push(slot_operand);
271 break; 271 break;
272 } 272 }
273 break; 273 break;
274 } 274 }
275 275
276 case Expression::kTest: 276 case Expression::kTest:
277 // For simplicity we always test the accumulator register. 277 // For simplicity we always test the accumulator register.
278 Move(result_register(), slot); 278 Move(result_register(), slot);
279 DoTest(true_label_, false_label_, NULL); 279 DoTest(true_label_, false_label_, fall_through_);
280 break; 280 break;
281 } 281 }
282 } 282 }
283 283
284 284
285 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) { 285 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
286 switch (context) { 286 switch (context) {
287 case Expression::kUninitialized: 287 case Expression::kUninitialized:
288 UNREACHABLE(); 288 UNREACHABLE();
289 case Expression::kEffect: 289 case Expression::kEffect:
290 // Nothing to do. 290 // Nothing to do.
291 break; 291 break;
292 case Expression::kValue: 292 case Expression::kValue:
293 switch (location_) { 293 switch (location_) {
294 case kAccumulator: 294 case kAccumulator:
295 __ mov(result_register(), lit->handle()); 295 __ mov(result_register(), lit->handle());
296 break; 296 break;
297 case kStack: 297 case kStack:
298 // Immediates can be pushed directly. 298 // Immediates can be pushed directly.
299 __ push(Immediate(lit->handle())); 299 __ push(Immediate(lit->handle()));
300 break; 300 break;
301 } 301 }
302 break; 302 break;
303 303
304 case Expression::kTest: 304 case Expression::kTest:
305 // For simplicity we always test the accumulator register. 305 // For simplicity we always test the accumulator register.
306 __ mov(result_register(), lit->handle()); 306 __ mov(result_register(), lit->handle());
307 DoTest(true_label_, false_label_, NULL); 307 DoTest(true_label_, false_label_, fall_through_);
308 break; 308 break;
309 } 309 }
310 } 310 }
311 311
312 312
313 void FullCodeGenerator::ApplyTOS(Expression::Context context) { 313 void FullCodeGenerator::ApplyTOS(Expression::Context context) {
314 switch (context) { 314 switch (context) {
315 case Expression::kUninitialized: 315 case Expression::kUninitialized:
316 UNREACHABLE(); 316 UNREACHABLE();
317 317
318 case Expression::kEffect: 318 case Expression::kEffect:
319 __ Drop(1); 319 __ Drop(1);
320 break; 320 break;
321 321
322 case Expression::kValue: 322 case Expression::kValue:
323 switch (location_) { 323 switch (location_) {
324 case kAccumulator: 324 case kAccumulator:
325 __ pop(result_register()); 325 __ pop(result_register());
326 break; 326 break;
327 case kStack: 327 case kStack:
328 break; 328 break;
329 } 329 }
330 break; 330 break;
331 331
332 case Expression::kTest: 332 case Expression::kTest:
333 // For simplicity we always test the accumulator register. 333 // For simplicity we always test the accumulator register.
334 __ pop(result_register()); 334 __ pop(result_register());
335 DoTest(true_label_, false_label_, NULL); 335 DoTest(true_label_, false_label_, fall_through_);
336 break; 336 break;
337 } 337 }
338 } 338 }
339 339
340 340
341 void FullCodeGenerator::DropAndApply(int count, 341 void FullCodeGenerator::DropAndApply(int count,
342 Expression::Context context, 342 Expression::Context context,
343 Register reg) { 343 Register reg) {
344 ASSERT(count > 0); 344 ASSERT(count > 0);
345 ASSERT(!reg.is(esp)); 345 ASSERT(!reg.is(esp));
(...skipping 15 matching lines...) Expand all
361 if (count > 1) __ Drop(count - 1); 361 if (count > 1) __ Drop(count - 1);
362 __ mov(Operand(esp, 0), reg); 362 __ mov(Operand(esp, 0), reg);
363 break; 363 break;
364 } 364 }
365 break; 365 break;
366 366
367 case Expression::kTest: 367 case Expression::kTest:
368 // For simplicity we always test the accumulator register. 368 // For simplicity we always test the accumulator register.
369 __ Drop(count); 369 __ Drop(count);
370 if (!reg.is(result_register())) __ mov(result_register(), reg); 370 if (!reg.is(result_register())) __ mov(result_register(), reg);
371 DoTest(true_label_, false_label_, NULL); 371 DoTest(true_label_, false_label_, fall_through_);
372 break;
373 }
374 }
375
376
377 void FullCodeGenerator::PrepareTest(Label* materialize_true,
378 Label* materialize_false,
379 Label** if_true,
380 Label** if_false) {
381 switch (context_) {
382 case Expression::kUninitialized:
383 UNREACHABLE();
384 break;
385 case Expression::kEffect:
386 // In an effect context, the true and the false case branch to the
387 // same label.
388 *if_true = *if_false = materialize_true;
389 break;
390 case Expression::kValue:
391 *if_true = materialize_true;
392 *if_false = materialize_false;
393 break;
394 case Expression::kTest:
395 *if_true = true_label_;
396 *if_false = false_label_;
397 break; 372 break;
398 } 373 }
399 } 374 }
400 375
401 376
402 void FullCodeGenerator::Apply(Expression::Context context, 377 void FullCodeGenerator::Apply(Expression::Context context,
403 Label* materialize_true, 378 Label* materialize_true,
404 Label* materialize_false) { 379 Label* materialize_false) {
405 switch (context) { 380 switch (context) {
406 case Expression::kUninitialized: 381 case Expression::kUninitialized:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 case kAccumulator: 429 case kAccumulator:
455 __ mov(result_register(), value); 430 __ mov(result_register(), value);
456 break; 431 break;
457 case kStack: 432 case kStack:
458 __ push(Immediate(value)); 433 __ push(Immediate(value));
459 break; 434 break;
460 } 435 }
461 break; 436 break;
462 } 437 }
463 case Expression::kTest: 438 case Expression::kTest:
464 __ jmp(flag ? true_label_ : false_label_); 439 if (flag) {
440 if (true_label_ != fall_through_) __ jmp(true_label_);
441 } else {
442 if (false_label_ != fall_through_) __ jmp(false_label_);
443 }
465 break; 444 break;
466 } 445 }
467 } 446 }
468 447
469 448
470 void FullCodeGenerator::DoTest(Label* if_true, 449 void FullCodeGenerator::DoTest(Label* if_true,
471 Label* if_false, 450 Label* if_false,
472 Label* fall_through) { 451 Label* fall_through) {
473 // Emit the inlined tests assumed by the stub. 452 // Emit the inlined tests assumed by the stub.
474 __ cmp(result_register(), Factory::undefined_value()); 453 __ cmp(result_register(), Factory::undefined_value());
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 1707
1729 1708
1730 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 1709 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1731 ASSERT(args->length() == 1); 1710 ASSERT(args->length() == 1);
1732 1711
1733 VisitForValue(args->at(0), kAccumulator); 1712 VisitForValue(args->at(0), kAccumulator);
1734 1713
1735 Label materialize_true, materialize_false; 1714 Label materialize_true, materialize_false;
1736 Label* if_true = NULL; 1715 Label* if_true = NULL;
1737 Label* if_false = NULL; 1716 Label* if_false = NULL;
1738 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1717 Label* fall_through = NULL;
1718 PrepareTest(&materialize_true, &materialize_false,
1719 &if_true, &if_false, &fall_through);
1739 1720
1740 __ test(eax, Immediate(kSmiTagMask)); 1721 __ test(eax, Immediate(kSmiTagMask));
1741 Split(zero, if_true, if_false, NULL); 1722 Split(zero, if_true, if_false, fall_through);
1742 1723
1743 Apply(context_, if_true, if_false); 1724 Apply(context_, if_true, if_false);
1744 } 1725 }
1745 1726
1746 1727
1747 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { 1728 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
1748 ASSERT(args->length() == 1); 1729 ASSERT(args->length() == 1);
1749 1730
1750 VisitForValue(args->at(0), kAccumulator); 1731 VisitForValue(args->at(0), kAccumulator);
1751 1732
1752 Label materialize_true, materialize_false; 1733 Label materialize_true, materialize_false;
1753 Label* if_true = NULL; 1734 Label* if_true = NULL;
1754 Label* if_false = NULL; 1735 Label* if_false = NULL;
1755 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1736 Label* fall_through = NULL;
1737 PrepareTest(&materialize_true, &materialize_false,
1738 &if_true, &if_false, &fall_through);
1756 1739
1757 __ test(eax, Immediate(kSmiTagMask | 0x80000000)); 1740 __ test(eax, Immediate(kSmiTagMask | 0x80000000));
1758 Split(zero, if_true, if_false, NULL); 1741 Split(zero, if_true, if_false, fall_through);
1759 1742
1760 Apply(context_, if_true, if_false); 1743 Apply(context_, if_true, if_false);
1761 } 1744 }
1762 1745
1763 1746
1764 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { 1747 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
1765 ASSERT(args->length() == 1); 1748 ASSERT(args->length() == 1);
1766 1749
1767 VisitForValue(args->at(0), kAccumulator); 1750 VisitForValue(args->at(0), kAccumulator);
1768 1751
1769 Label materialize_true, materialize_false; 1752 Label materialize_true, materialize_false;
1770 Label* if_true = NULL; 1753 Label* if_true = NULL;
1771 Label* if_false = NULL; 1754 Label* if_false = NULL;
1772 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1755 Label* fall_through = NULL;
1756 PrepareTest(&materialize_true, &materialize_false,
1757 &if_true, &if_false, &fall_through);
1773 1758
1774 __ test(eax, Immediate(kSmiTagMask)); 1759 __ test(eax, Immediate(kSmiTagMask));
1775 __ j(zero, if_false); 1760 __ j(zero, if_false);
1776 __ cmp(eax, Factory::null_value()); 1761 __ cmp(eax, Factory::null_value());
1777 __ j(equal, if_true); 1762 __ j(equal, if_true);
1778 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 1763 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1779 // Undetectable objects behave like undefined when tested with typeof. 1764 // Undetectable objects behave like undefined when tested with typeof.
1780 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset)); 1765 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset));
1781 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 1766 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
1782 __ j(not_zero, if_false); 1767 __ j(not_zero, if_false);
1783 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 1768 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
1784 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 1769 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
1785 __ j(below, if_false); 1770 __ j(below, if_false);
1786 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 1771 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
1787 Split(below_equal, if_true, if_false, NULL); 1772 Split(below_equal, if_true, if_false, fall_through);
1788 1773
1789 Apply(context_, if_true, if_false); 1774 Apply(context_, if_true, if_false);
1790 } 1775 }
1791 1776
1792 1777
1793 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { 1778 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
1794 ASSERT(args->length() == 1); 1779 ASSERT(args->length() == 1);
1795 1780
1796 VisitForValue(args->at(0), kAccumulator); 1781 VisitForValue(args->at(0), kAccumulator);
1797 1782
1798 Label materialize_true, materialize_false; 1783 Label materialize_true, materialize_false;
1799 Label* if_true = NULL; 1784 Label* if_true = NULL;
1800 Label* if_false = NULL; 1785 Label* if_false = NULL;
1801 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1786 Label* fall_through = NULL;
1787 PrepareTest(&materialize_true, &materialize_false,
1788 &if_true, &if_false, &fall_through);
1802 1789
1803 __ test(eax, Immediate(kSmiTagMask)); 1790 __ test(eax, Immediate(kSmiTagMask));
1804 __ j(equal, if_false); 1791 __ j(equal, if_false);
1805 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx); 1792 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx);
1806 Split(above_equal, if_true, if_false, NULL); 1793 Split(above_equal, if_true, if_false, fall_through);
1807 1794
1808 Apply(context_, if_true, if_false); 1795 Apply(context_, if_true, if_false);
1809 } 1796 }
1810 1797
1811 1798
1812 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { 1799 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
1813 ASSERT(args->length() == 1); 1800 ASSERT(args->length() == 1);
1814 1801
1815 VisitForValue(args->at(0), kAccumulator); 1802 VisitForValue(args->at(0), kAccumulator);
1816 1803
1817 Label materialize_true, materialize_false; 1804 Label materialize_true, materialize_false;
1818 Label* if_true = NULL; 1805 Label* if_true = NULL;
1819 Label* if_false = NULL; 1806 Label* if_false = NULL;
1820 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1807 Label* fall_through = NULL;
1808 PrepareTest(&materialize_true, &materialize_false,
1809 &if_true, &if_false, &fall_through);
1821 1810
1822 __ test(eax, Immediate(kSmiTagMask)); 1811 __ test(eax, Immediate(kSmiTagMask));
1823 __ j(zero, if_false); 1812 __ j(zero, if_false);
1824 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 1813 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1825 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); 1814 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
1826 __ test(ebx, Immediate(1 << Map::kIsUndetectable)); 1815 __ test(ebx, Immediate(1 << Map::kIsUndetectable));
1827 Split(not_zero, if_true, if_false, NULL); 1816 Split(not_zero, if_true, if_false, fall_through);
1828 1817
1829 Apply(context_, if_true, if_false); 1818 Apply(context_, if_true, if_false);
1830 } 1819 }
1831 1820
1832 1821
1833 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 1822 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
1834 ZoneList<Expression*>* args) { 1823 ZoneList<Expression*>* args) {
1835 ASSERT(args->length() == 1); 1824 ASSERT(args->length() == 1);
1836 1825
1837 VisitForValue(args->at(0), kAccumulator); 1826 VisitForValue(args->at(0), kAccumulator);
1838 1827
1839 Label materialize_true, materialize_false; 1828 Label materialize_true, materialize_false;
1840 Label* if_true = NULL; 1829 Label* if_true = NULL;
1841 Label* if_false = NULL; 1830 Label* if_false = NULL;
1842 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1831 Label* fall_through = NULL;
1832 PrepareTest(&materialize_true, &materialize_false,
1833 &if_true, &if_false, &fall_through);
1843 1834
1844 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only 1835 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only
1845 // used in a few functions in runtime.js which should not normally be hit by 1836 // used in a few functions in runtime.js which should not normally be hit by
1846 // this compiler. 1837 // this compiler.
1847 __ jmp(if_false); 1838 __ jmp(if_false);
1848 Apply(context_, if_true, if_false); 1839 Apply(context_, if_true, if_false);
1849 } 1840 }
1850 1841
1851 1842
1852 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 1843 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
1853 ASSERT(args->length() == 1); 1844 ASSERT(args->length() == 1);
1854 1845
1855 VisitForValue(args->at(0), kAccumulator); 1846 VisitForValue(args->at(0), kAccumulator);
1856 1847
1857 Label materialize_true, materialize_false; 1848 Label materialize_true, materialize_false;
1858 Label* if_true = NULL; 1849 Label* if_true = NULL;
1859 Label* if_false = NULL; 1850 Label* if_false = NULL;
1860 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1851 Label* fall_through = NULL;
1852 PrepareTest(&materialize_true, &materialize_false,
1853 &if_true, &if_false, &fall_through);
1861 1854
1862 __ test(eax, Immediate(kSmiTagMask)); 1855 __ test(eax, Immediate(kSmiTagMask));
1863 __ j(zero, if_false); 1856 __ j(zero, if_false);
1864 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 1857 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
1865 Split(equal, if_true, if_false, NULL); 1858 Split(equal, if_true, if_false, fall_through);
1866 1859
1867 Apply(context_, if_true, if_false); 1860 Apply(context_, if_true, if_false);
1868 } 1861 }
1869 1862
1870 1863
1871 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { 1864 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
1872 ASSERT(args->length() == 1); 1865 ASSERT(args->length() == 1);
1873 1866
1874 VisitForValue(args->at(0), kAccumulator); 1867 VisitForValue(args->at(0), kAccumulator);
1875 1868
1876 Label materialize_true, materialize_false; 1869 Label materialize_true, materialize_false;
1877 Label* if_true = NULL; 1870 Label* if_true = NULL;
1878 Label* if_false = NULL; 1871 Label* if_false = NULL;
1879 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1872 Label* fall_through = NULL;
1873 PrepareTest(&materialize_true, &materialize_false,
1874 &if_true, &if_false, &fall_through);
1880 1875
1881 __ test(eax, Immediate(kSmiTagMask)); 1876 __ test(eax, Immediate(kSmiTagMask));
1882 __ j(equal, if_false); 1877 __ j(equal, if_false);
1883 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); 1878 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
1884 Split(equal, if_true, if_false, NULL); 1879 Split(equal, if_true, if_false, fall_through);
1885 1880
1886 Apply(context_, if_true, if_false); 1881 Apply(context_, if_true, if_false);
1887 } 1882 }
1888 1883
1889 1884
1890 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { 1885 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
1891 ASSERT(args->length() == 1); 1886 ASSERT(args->length() == 1);
1892 1887
1893 VisitForValue(args->at(0), kAccumulator); 1888 VisitForValue(args->at(0), kAccumulator);
1894 1889
1895 Label materialize_true, materialize_false; 1890 Label materialize_true, materialize_false;
1896 Label* if_true = NULL; 1891 Label* if_true = NULL;
1897 Label* if_false = NULL; 1892 Label* if_false = NULL;
1898 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1893 Label* fall_through = NULL;
1894 PrepareTest(&materialize_true, &materialize_false,
1895 &if_true, &if_false, &fall_through);
1899 1896
1900 __ test(eax, Immediate(kSmiTagMask)); 1897 __ test(eax, Immediate(kSmiTagMask));
1901 __ j(equal, if_false); 1898 __ j(equal, if_false);
1902 __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx); 1899 __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx);
1903 Split(equal, if_true, if_false, NULL); 1900 Split(equal, if_true, if_false, fall_through);
1904 1901
1905 Apply(context_, if_true, if_false); 1902 Apply(context_, if_true, if_false);
1906 } 1903 }
1907 1904
1908 1905
1909 1906
1910 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { 1907 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
1911 ASSERT(args->length() == 0); 1908 ASSERT(args->length() == 0);
1912 1909
1913 Label materialize_true, materialize_false; 1910 Label materialize_true, materialize_false;
1914 Label* if_true = NULL; 1911 Label* if_true = NULL;
1915 Label* if_false = NULL; 1912 Label* if_false = NULL;
1916 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1913 Label* fall_through = NULL;
1914 PrepareTest(&materialize_true, &materialize_false,
1915 &if_true, &if_false, &fall_through);
1917 1916
1918 // Get the frame pointer for the calling frame. 1917 // Get the frame pointer for the calling frame.
1919 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 1918 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1920 1919
1921 // Skip the arguments adaptor frame if it exists. 1920 // Skip the arguments adaptor frame if it exists.
1922 Label check_frame_marker; 1921 Label check_frame_marker;
1923 __ cmp(Operand(eax, StandardFrameConstants::kContextOffset), 1922 __ cmp(Operand(eax, StandardFrameConstants::kContextOffset),
1924 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1923 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1925 __ j(not_equal, &check_frame_marker); 1924 __ j(not_equal, &check_frame_marker);
1926 __ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset)); 1925 __ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset));
1927 1926
1928 // Check the marker in the calling frame. 1927 // Check the marker in the calling frame.
1929 __ bind(&check_frame_marker); 1928 __ bind(&check_frame_marker);
1930 __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset), 1929 __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset),
1931 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 1930 Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
1932 Split(equal, if_true, if_false, NULL); 1931 Split(equal, if_true, if_false, fall_through);
1933 1932
1934 Apply(context_, if_true, if_false); 1933 Apply(context_, if_true, if_false);
1935 } 1934 }
1936 1935
1937 1936
1938 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { 1937 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
1939 ASSERT(args->length() == 2); 1938 ASSERT(args->length() == 2);
1940 1939
1941 // Load the two objects into registers and perform the comparison. 1940 // Load the two objects into registers and perform the comparison.
1942 VisitForValue(args->at(0), kStack); 1941 VisitForValue(args->at(0), kStack);
1943 VisitForValue(args->at(1), kAccumulator); 1942 VisitForValue(args->at(1), kAccumulator);
1944 1943
1945 Label materialize_true, materialize_false; 1944 Label materialize_true, materialize_false;
1946 Label* if_true = NULL; 1945 Label* if_true = NULL;
1947 Label* if_false = NULL; 1946 Label* if_false = NULL;
1948 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1947 Label* fall_through = NULL;
1948 PrepareTest(&materialize_true, &materialize_false,
1949 &if_true, &if_false, &fall_through);
1949 1950
1950 __ pop(ebx); 1951 __ pop(ebx);
1951 __ cmp(eax, Operand(ebx)); 1952 __ cmp(eax, Operand(ebx));
1952 Split(equal, if_true, if_false, NULL); 1953 Split(equal, if_true, if_false, fall_through);
1953 1954
1954 Apply(context_, if_true, if_false); 1955 Apply(context_, if_true, if_false);
1955 } 1956 }
1956 1957
1957 1958
1958 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 1959 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
1959 ASSERT(args->length() == 1); 1960 ASSERT(args->length() == 1);
1960 1961
1961 // ArgumentsAccessStub expects the key in edx and the formal 1962 // ArgumentsAccessStub expects the key in edx and the formal
1962 // parameter count in eax. 1963 // parameter count in eax.
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 break; 2607 break;
2607 case Expression::kTest: 2608 case Expression::kTest:
2608 __ jmp(false_label_); 2609 __ jmp(false_label_);
2609 break; 2610 break;
2610 } 2611 }
2611 break; 2612 break;
2612 } 2613 }
2613 2614
2614 case Token::NOT: { 2615 case Token::NOT: {
2615 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 2616 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
2617
2616 Label materialize_true, materialize_false; 2618 Label materialize_true, materialize_false;
2617 Label* if_true = NULL; 2619 Label* if_true = NULL;
2618 Label* if_false = NULL; 2620 Label* if_false = NULL;
2619 2621 Label* fall_through = NULL;
2620 // Notice that the labels are swapped. 2622 // Notice that the labels are swapped.
2621 PrepareTest(&materialize_true, &materialize_false, &if_false, &if_true); 2623 PrepareTest(&materialize_true, &materialize_false,
2622 2624 &if_false, &if_true, &fall_through);
2623 VisitForControl(expr->expression(), if_true, if_false); 2625 VisitForControl(expr->expression(), if_true, if_false, fall_through);
2624
2625 Apply(context_, if_false, if_true); // Labels swapped. 2626 Apply(context_, if_false, if_true); // Labels swapped.
2626 break; 2627 break;
2627 } 2628 }
2628 2629
2629 case Token::TYPEOF: { 2630 case Token::TYPEOF: {
2630 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 2631 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
2631 VisitForTypeofValue(expr->expression(), kStack); 2632 VisitForTypeofValue(expr->expression(), kStack);
2632 __ CallRuntime(Runtime::kTypeof, 1); 2633 __ CallRuntime(Runtime::kTypeof, 1);
2633 Apply(context_, eax); 2634 Apply(context_, eax);
2634 break; 2635 break;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2981 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 2982 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
2982 Comment cmnt(masm_, "[ CompareOperation"); 2983 Comment cmnt(masm_, "[ CompareOperation");
2983 SetSourcePosition(expr->position()); 2984 SetSourcePosition(expr->position());
2984 2985
2985 // Always perform the comparison for its control flow. Pack the result 2986 // Always perform the comparison for its control flow. Pack the result
2986 // into the expression's context after the comparison is performed. 2987 // into the expression's context after the comparison is performed.
2987 2988
2988 Label materialize_true, materialize_false; 2989 Label materialize_true, materialize_false;
2989 Label* if_true = NULL; 2990 Label* if_true = NULL;
2990 Label* if_false = NULL; 2991 Label* if_false = NULL;
2991 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 2992 Label* fall_through = NULL;
2993 PrepareTest(&materialize_true, &materialize_false,
2994 &if_true, &if_false, &fall_through);
2992 2995
2993 // First we try a fast inlined version of the compare when one of 2996 // First we try a fast inlined version of the compare when one of
2994 // the operands is a literal. 2997 // the operands is a literal.
2995 Token::Value op = expr->op(); 2998 Token::Value op = expr->op();
2996 Expression* left = expr->left(); 2999 Expression* left = expr->left();
2997 Expression* right = expr->right(); 3000 Expression* right = expr->right();
2998 if (TryLiteralCompare(op, left, right, if_true, if_false, NULL)) { 3001 if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
2999 Apply(context_, if_true, if_false); 3002 Apply(context_, if_true, if_false);
3000 return; 3003 return;
3001 } 3004 }
3002 3005
3003 VisitForValue(expr->left(), kStack); 3006 VisitForValue(expr->left(), kStack);
3004 switch (expr->op()) { 3007 switch (expr->op()) {
3005 case Token::IN: 3008 case Token::IN:
3006 VisitForValue(expr->right(), kStack); 3009 VisitForValue(expr->right(), kStack);
3007 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 3010 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
3008 __ cmp(eax, Factory::true_value()); 3011 __ cmp(eax, Factory::true_value());
3009 Split(equal, if_true, if_false, NULL); 3012 Split(equal, if_true, if_false, fall_through);
3010 break; 3013 break;
3011 3014
3012 case Token::INSTANCEOF: { 3015 case Token::INSTANCEOF: {
3013 VisitForValue(expr->right(), kStack); 3016 VisitForValue(expr->right(), kStack);
3014 InstanceofStub stub; 3017 InstanceofStub stub;
3015 __ CallStub(&stub); 3018 __ CallStub(&stub);
3016 __ test(eax, Operand(eax)); 3019 __ test(eax, Operand(eax));
3017 // The stub returns 0 for true. 3020 // The stub returns 0 for true.
3018 Split(zero, if_true, if_false, NULL); 3021 Split(zero, if_true, if_false, fall_through);
3019 break; 3022 break;
3020 } 3023 }
3021 3024
3022 default: { 3025 default: {
3023 VisitForValue(expr->right(), kAccumulator); 3026 VisitForValue(expr->right(), kAccumulator);
3024 Condition cc = no_condition; 3027 Condition cc = no_condition;
3025 bool strict = false; 3028 bool strict = false;
3026 switch (expr->op()) { 3029 switch (expr->op()) {
3027 case Token::EQ_STRICT: 3030 case Token::EQ_STRICT:
3028 strict = true; 3031 strict = true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 __ test(ecx, Immediate(kSmiTagMask)); 3068 __ test(ecx, Immediate(kSmiTagMask));
3066 __ j(not_zero, &slow_case, not_taken); 3069 __ j(not_zero, &slow_case, not_taken);
3067 __ cmp(edx, Operand(eax)); 3070 __ cmp(edx, Operand(eax));
3068 __ j(cc, if_true); 3071 __ j(cc, if_true);
3069 __ jmp(if_false); 3072 __ jmp(if_false);
3070 3073
3071 __ bind(&slow_case); 3074 __ bind(&slow_case);
3072 CompareStub stub(cc, strict); 3075 CompareStub stub(cc, strict);
3073 __ CallStub(&stub); 3076 __ CallStub(&stub);
3074 __ test(eax, Operand(eax)); 3077 __ test(eax, Operand(eax));
3075 Split(cc, if_true, if_false, NULL); 3078 Split(cc, if_true, if_false, fall_through);
3076 } 3079 }
3077 } 3080 }
3078 3081
3079 // Convert the result of the comparison into one expected for this 3082 // Convert the result of the comparison into one expected for this
3080 // expression's context. 3083 // expression's context.
3081 Apply(context_, if_true, if_false); 3084 Apply(context_, if_true, if_false);
3082 } 3085 }
3083 3086
3084 3087
3085 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) { 3088 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) {
3086 Label materialize_true, materialize_false; 3089 Label materialize_true, materialize_false;
3087 Label* if_true = NULL; 3090 Label* if_true = NULL;
3088 Label* if_false = NULL; 3091 Label* if_false = NULL;
3089 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 3092 Label* fall_through = NULL;
3093 PrepareTest(&materialize_true, &materialize_false,
3094 &if_true, &if_false, &fall_through);
3090 3095
3091 VisitForValue(expr->expression(), kAccumulator); 3096 VisitForValue(expr->expression(), kAccumulator);
3092 __ cmp(eax, Factory::null_value()); 3097 __ cmp(eax, Factory::null_value());
3093 if (expr->is_strict()) { 3098 if (expr->is_strict()) {
3094 Split(equal, if_true, if_false, NULL); 3099 Split(equal, if_true, if_false, fall_through);
3095 } else { 3100 } else {
3096 __ j(equal, if_true); 3101 __ j(equal, if_true);
3097 __ cmp(eax, Factory::undefined_value()); 3102 __ cmp(eax, Factory::undefined_value());
3098 __ j(equal, if_true); 3103 __ j(equal, if_true);
3099 __ test(eax, Immediate(kSmiTagMask)); 3104 __ test(eax, Immediate(kSmiTagMask));
3100 __ j(zero, if_false); 3105 __ j(zero, if_false);
3101 // It can be an undetectable object. 3106 // It can be an undetectable object.
3102 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 3107 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
3103 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); 3108 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
3104 __ test(edx, Immediate(1 << Map::kIsUndetectable)); 3109 __ test(edx, Immediate(1 << Map::kIsUndetectable));
3105 Split(not_zero, if_true, if_false, NULL); 3110 Split(not_zero, if_true, if_false, fall_through);
3106 } 3111 }
3107 Apply(context_, if_true, if_false); 3112 Apply(context_, if_true, if_false);
3108 } 3113 }
3109 3114
3110 3115
3111 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3116 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
3112 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3117 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3113 Apply(context_, eax); 3118 Apply(context_, eax);
3114 } 3119 }
3115 3120
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 // And return. 3165 // And return.
3161 __ ret(0); 3166 __ ret(0);
3162 } 3167 }
3163 3168
3164 3169
3165 #undef __ 3170 #undef __
3166 3171
3167 } } // namespace v8::internal 3172 } } // namespace v8::internal
3168 3173
3169 #endif // V8_TARGET_ARCH_IA32 3174 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698