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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 3388005: Make the CompareStub and the UnaryOpStub accept smi inputs.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: x64 and ARM port 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
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 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 __ SmiToInteger32(kScratchRegister, rax); 1397 __ SmiToInteger32(kScratchRegister, rax);
1398 __ cvtlsi2sd(xmm1, kScratchRegister); 1398 __ cvtlsi2sd(xmm1, kScratchRegister);
1399 __ bind(&done); 1399 __ bind(&done);
1400 } 1400 }
1401 1401
1402 1402
1403 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { 1403 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
1404 Label slow, done; 1404 Label slow, done;
1405 1405
1406 if (op_ == Token::SUB) { 1406 if (op_ == Token::SUB) {
1407 // Check whether the value is a smi. 1407 if (include_smi_code_) {
1408 Label try_float; 1408 // Check whether the value is a smi.
1409 __ JumpIfNotSmi(rax, &try_float); 1409 Label try_float;
1410 __ JumpIfNotSmi(rax, &try_float);
1411 if (negative_zero_ == kIgnoreNegativeZero) {
1412 __ SmiCompare(rax, Smi::FromInt(0));
1413 __ j(equal, &done);
1414 }
1415 __ SmiNeg(rax, rax, &done);
1410 1416
1411 if (negative_zero_ == kIgnoreNegativeZero) { 1417 // Either zero or Smi::kMinValue, neither of which become a smi when
1412 __ SmiCompare(rax, Smi::FromInt(0)); 1418 // negated. We handle negative zero here if required. We always enter
1413 __ j(equal, &done); 1419 // the runtime system if we have Smi::kMinValue.
1420 if (negative_zero_ == kStrictNegativeZero) {
1421 __ SmiCompare(rax, Smi::FromInt(0));
1422 __ j(not_equal, &slow);
1423 __ Move(rax, Factory::minus_zero_value());
1424 __ jmp(&done);
1425 } else {
1426 __ SmiCompare(rax, Smi::FromInt(Smi::kMinValue));
1427 __ j(equal, &slow);
1428 __ jmp(&done);
1429 }
1430 // Try floating point case.
1431 __ bind(&try_float);
1432 } else if (FLAG_debug_code) {
1433 __ AbortIfSmi(rax);
1414 } 1434 }
1415 1435
1416 // Enter runtime system if the value of the smi is zero
1417 // to make sure that we switch between 0 and -0.
1418 // Also enter it if the value of the smi is Smi::kMinValue.
1419 __ SmiNeg(rax, rax, &done);
1420
1421 // Either zero or Smi::kMinValue, neither of which become a smi when
1422 // negated.
1423 if (negative_zero_ == kStrictNegativeZero) {
1424 __ SmiCompare(rax, Smi::FromInt(0));
1425 __ j(not_equal, &slow);
1426 __ Move(rax, Factory::minus_zero_value());
1427 __ jmp(&done);
1428 } else {
1429 __ jmp(&slow);
1430 }
1431
1432 // Try floating point case.
1433 __ bind(&try_float);
1434 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 1436 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
1435 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); 1437 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
1436 __ j(not_equal, &slow); 1438 __ j(not_equal, &slow);
1437 // Operand is a float, negate its value by flipping sign bit. 1439 // Operand is a float, negate its value by flipping sign bit.
1438 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); 1440 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
1439 __ movq(kScratchRegister, Immediate(0x01)); 1441 __ movq(kScratchRegister, Immediate(0x01));
1440 __ shl(kScratchRegister, Immediate(63)); 1442 __ shl(kScratchRegister, Immediate(63));
1441 __ xor_(rdx, kScratchRegister); // Flip sign. 1443 __ xor_(rdx, kScratchRegister); // Flip sign.
1442 // rdx is value to store. 1444 // rdx is value to store.
1443 if (overwrite_ == UNARY_OVERWRITE) { 1445 if (overwrite_ == UNARY_OVERWRITE) {
1444 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); 1446 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
1445 } else { 1447 } else {
1446 __ AllocateHeapNumber(rcx, rbx, &slow); 1448 __ AllocateHeapNumber(rcx, rbx, &slow);
1447 // rcx: allocated 'empty' number 1449 // rcx: allocated 'empty' number
1448 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); 1450 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
1449 __ movq(rax, rcx); 1451 __ movq(rax, rcx);
1450 } 1452 }
1451 } else if (op_ == Token::BIT_NOT) { 1453 } else if (op_ == Token::BIT_NOT) {
1454 if (include_smi_code_) {
1455 Label try_float;
1456 __ JumpIfNotSmi(rax, &try_float);
1457 __ SmiNot(rax, rax);
1458 __ jmp(&done);
1459 // Try floating point case.
1460 __ bind(&try_float);
1461 } else if (FLAG_debug_code) {
1462 __ AbortIfSmi(rax);
1463 }
1464
1452 // Check if the operand is a heap number. 1465 // Check if the operand is a heap number.
1453 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 1466 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
1454 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); 1467 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
1455 __ j(not_equal, &slow); 1468 __ j(not_equal, &slow);
1456 1469
1457 // Convert the heap number in rax to an untagged integer in rcx. 1470 // Convert the heap number in rax to an untagged integer in rcx.
1458 IntegerConvert(masm, rax, rax); 1471 IntegerConvert(masm, rax, rax);
1459 1472
1460 // Do the bitwise operation and smi tag the result. 1473 // Do the bitwise operation and smi tag the result.
1461 __ notl(rax); 1474 __ notl(rax);
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 ASSERT((cc == less) || (cc == less_equal) 2121 ASSERT((cc == less) || (cc == less_equal)
2109 || (cc == greater) || (cc == greater_equal)); 2122 || (cc == greater) || (cc == greater_equal));
2110 return (cc == greater || cc == greater_equal) ? LESS : GREATER; 2123 return (cc == greater || cc == greater_equal) ? LESS : GREATER;
2111 } 2124 }
2112 2125
2113 2126
2114 void CompareStub::Generate(MacroAssembler* masm) { 2127 void CompareStub::Generate(MacroAssembler* masm) {
2115 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); 2128 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
2116 2129
2117 Label check_unequal_objects, done; 2130 Label check_unequal_objects, done;
2131
2132 // Compare two smis if required.
2133 if (include_smi_compare_) {
2134 Label non_smi, smi_done;
2135 __ JumpIfNotBothSmi(rax, rdx, &non_smi);
2136 __ subq(rdx, rax);
2137 __ j(no_overflow, &smi_done);
2138 __ neg(rdx); // Correct sign in case of overflow.
2139 __ bind(&smi_done);
2140 __ movq(rax, rdx);
2141 __ ret(0);
2142 __ bind(&non_smi);
2143 } else if (FLAG_debug_code) {
2144 Label ok;
2145 __ JumpIfNotSmi(rdx, &ok);
2146 __ JumpIfNotSmi(rax, &ok);
2147 __ Abort("CompareStub: smi operands");
2148 __ bind(&ok);
2149 }
2150
2118 // The compare stub returns a positive, negative, or zero 64-bit integer 2151 // The compare stub returns a positive, negative, or zero 64-bit integer
2119 // value in rax, corresponding to result of comparing the two inputs. 2152 // value in rax, corresponding to result of comparing the two inputs.
2120 // NOTICE! This code is only reached after a smi-fast-case check, so 2153 // NOTICE! This code is only reached after a smi-fast-case check, so
2121 // it is certain that at least one operand isn't a smi. 2154 // it is certain that at least one operand isn't a smi.
2122 2155
2123 // Two identical objects are equal unless they are both NaN or undefined. 2156 // Two identical objects are equal unless they are both NaN or undefined.
2124 { 2157 {
2125 Label not_identical; 2158 Label not_identical;
2126 __ cmpq(rax, rdx); 2159 __ cmpq(rax, rdx);
2127 __ j(not_equal, &not_identical); 2160 __ j(not_equal, &not_identical);
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 int CompareStub::MinorKey() { 3027 int CompareStub::MinorKey() {
2995 // Encode the three parameters in a unique 16 bit value. To avoid duplicate 3028 // Encode the three parameters in a unique 16 bit value. To avoid duplicate
2996 // stubs the never NaN NaN condition is only taken into account if the 3029 // stubs the never NaN NaN condition is only taken into account if the
2997 // condition is equals. 3030 // condition is equals.
2998 ASSERT(static_cast<unsigned>(cc_) < (1 << 12)); 3031 ASSERT(static_cast<unsigned>(cc_) < (1 << 12));
2999 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); 3032 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
3000 return ConditionField::encode(static_cast<unsigned>(cc_)) 3033 return ConditionField::encode(static_cast<unsigned>(cc_))
3001 | RegisterField::encode(false) // lhs_ and rhs_ are not used 3034 | RegisterField::encode(false) // lhs_ and rhs_ are not used
3002 | StrictField::encode(strict_) 3035 | StrictField::encode(strict_)
3003 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false) 3036 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false)
3004 | IncludeNumberCompareField::encode(include_number_compare_); 3037 | IncludeNumberCompareField::encode(include_number_compare_)
3038 | IncludeSmiCompareField::encode(include_smi_compare_);
3005 } 3039 }
3006 3040
3007 3041
3008 // Unfortunately you have to run without snapshots to see most of these 3042 // Unfortunately you have to run without snapshots to see most of these
3009 // names in the profile since most compare stubs end up in the snapshot. 3043 // names in the profile since most compare stubs end up in the snapshot.
3010 const char* CompareStub::GetName() { 3044 const char* CompareStub::GetName() {
3011 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); 3045 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
3012 3046
3013 if (name_ != NULL) return name_; 3047 if (name_ != NULL) return name_;
3014 const int kMaxNameLength = 100; 3048 const int kMaxNameLength = 100;
(...skipping 19 matching lines...) Expand all
3034 const char* never_nan_nan_name = ""; 3068 const char* never_nan_nan_name = "";
3035 if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) { 3069 if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
3036 never_nan_nan_name = "_NO_NAN"; 3070 never_nan_nan_name = "_NO_NAN";
3037 } 3071 }
3038 3072
3039 const char* include_number_compare_name = ""; 3073 const char* include_number_compare_name = "";
3040 if (!include_number_compare_) { 3074 if (!include_number_compare_) {
3041 include_number_compare_name = "_NO_NUMBER"; 3075 include_number_compare_name = "_NO_NUMBER";
3042 } 3076 }
3043 3077
3078 const char* include_smi_compare_name = "";
3079 if (!include_smi_compare_) {
3080 include_smi_compare_name = "_NO_SMI";
3081 }
3082
3044 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 3083 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
3045 "CompareStub_%s%s%s%s", 3084 "CompareStub_%s%s%s%s",
3046 cc_name, 3085 cc_name,
3047 strict_name, 3086 strict_name,
3048 never_nan_nan_name, 3087 never_nan_nan_name,
3049 include_number_compare_name); 3088 include_number_compare_name,
3089 include_smi_compare_name);
3050 return name_; 3090 return name_;
3051 } 3091 }
3052 3092
3053 3093
3054 // ------------------------------------------------------------------------- 3094 // -------------------------------------------------------------------------
3055 // StringCharCodeAtGenerator 3095 // StringCharCodeAtGenerator
3056 3096
3057 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3097 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3058 Label flat_string; 3098 Label flat_string;
3059 Label ascii_string; 3099 Label ascii_string;
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after
4006 // tagged as a small integer. 4046 // tagged as a small integer.
4007 __ bind(&runtime); 4047 __ bind(&runtime);
4008 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4048 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4009 } 4049 }
4010 4050
4011 #undef __ 4051 #undef __
4012 4052
4013 } } // namespace v8::internal 4053 } } // namespace v8::internal
4014 4054
4015 #endif // V8_TARGET_ARCH_X64 4055 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698