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

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

Issue 668254: Port of string plus smi optimization from ia32 to x64 and ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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/codegen-x64.h ('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 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 4024 matching lines...) Expand 10 before | Expand all | Expand 10 after
4035 frame_->Push(&result); 4035 frame_->Push(&result);
4036 } 4036 }
4037 4037
4038 4038
4039 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { 4039 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
4040 ASSERT_EQ(args->length(), 1); 4040 ASSERT_EQ(args->length(), 1);
4041 4041
4042 // Load the argument on the stack and jump to the runtime. 4042 // Load the argument on the stack and jump to the runtime.
4043 Load(args->at(0)); 4043 Load(args->at(0));
4044 4044
4045 Result answer = frame_->CallRuntime(Runtime::kNumberToString, 1); 4045 NumberToStringStub stub;
4046 frame_->Push(&answer); 4046 Result result = frame_->CallStub(&stub, 1);
4047 frame_->Push(&result);
4047 } 4048 }
4048 4049
4049 4050
4050 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { 4051 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
4051 ASSERT_EQ(args->length(), 1); 4052 ASSERT_EQ(args->length(), 1);
4052 // Load the argument on the stack and jump to the runtime. 4053 // Load the argument on the stack and jump to the runtime.
4053 Load(args->at(0)); 4054 Load(args->at(0));
4054 Result answer = frame_->CallRuntime(Runtime::kMath_sin, 1); 4055 Result answer = frame_->CallRuntime(Runtime::kMath_sin, 1);
4055 frame_->Push(&answer); 4056 frame_->Push(&answer);
4056 } 4057 }
(...skipping 3132 matching lines...) Expand 10 before | Expand all | Expand 10 after
7189 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 7190 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
7190 __ ret(4 * kPointerSize); 7191 __ ret(4 * kPointerSize);
7191 7192
7192 // Do the runtime call to execute the regexp. 7193 // Do the runtime call to execute the regexp.
7193 __ bind(&runtime); 7194 __ bind(&runtime);
7194 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 7195 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
7195 #endif // V8_NATIVE_REGEXP 7196 #endif // V8_NATIVE_REGEXP
7196 } 7197 }
7197 7198
7198 7199
7200 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
7201 Register object,
7202 Register result,
7203 Register scratch1,
7204 Register scratch2,
7205 bool object_is_smi,
7206 Label* not_found) {
7207 // Currently only lookup for smis. Check for smi if object is not known to be
7208 // a smi.
7209 if (!object_is_smi) {
7210 __ JumpIfNotSmi(object, not_found);
7211 }
7212
7213 // Use of registers. Register result is used as a temporary.
7214 Register number_string_cache = result;
7215 Register mask = scratch1;
7216 Register scratch = scratch2;
7217
7218 // Load the number string cache.
7219 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
7220
7221 // Make the hash mask from the length of the number string cache. It
7222 // contains two elements (number and string) for each cache entry.
7223 __ movl(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
7224 __ shrl(mask, Immediate(1)); // Divide length by two (length is not a smi).
7225 __ subl(mask, Immediate(1)); // Make mask.
7226
7227 // Calculate the entry in the number string cache. The hash value in the
7228 // number string cache for smis is just the smi value.
7229 __ movq(scratch, object);
7230 __ SmiToInteger32(scratch, scratch);
7231 __ andl(scratch, mask);
7232
7233 // Each entry in string cache consists of two pointer sized fields,
7234 // but times_twice_pointer_size (multiplication by 16) scale factor
7235 // is not supported by addrmode on x64 platform.
7236 // So we have to premultiply entry index before lookup
7237 __ shl(scratch, Immediate(kPointerSizeLog2 + 1));
7238 // Check if the entry is the smi we are looking for.
7239 __ cmpq(object,
7240 FieldOperand(number_string_cache,
7241 scratch,
7242 times_1,
7243 FixedArray::kHeaderSize));
7244 __ j(not_equal, not_found);
7245
7246 // Get the result from the cache.
7247 __ movq(result,
7248 FieldOperand(number_string_cache,
7249 scratch,
7250 times_1,
7251 FixedArray::kHeaderSize + kPointerSize));
7252 __ IncrementCounter(&Counters::number_to_string_native, 1);
7253 }
7254
7255
7256 void NumberToStringStub::Generate(MacroAssembler* masm) {
7257 Label runtime;
7258
7259 __ movq(rbx, Operand(rsp, kPointerSize));
7260
7261 // Generate code to lookup number in the number string cache.
7262 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
7263 __ ret(1 * kPointerSize);
7264
7265 __ bind(&runtime);
7266 // Handle number to string in the runtime system if not found in the cache.
7267 __ TailCallRuntime(Runtime::kNumberToString, 1, 1);
7268 }
7269
7270
7199 void CompareStub::Generate(MacroAssembler* masm) { 7271 void CompareStub::Generate(MacroAssembler* masm) {
7200 Label call_builtin, done; 7272 Label call_builtin, done;
7201 7273
7202 // NOTICE! This code is only reached after a smi-fast-case check, so 7274 // NOTICE! This code is only reached after a smi-fast-case check, so
7203 // it is certain that at least one operand isn't a smi. 7275 // it is certain that at least one operand isn't a smi.
7204 7276
7205 if (cc_ == equal) { // Both strict and non-strict. 7277 if (cc_ == equal) { // Both strict and non-strict.
7206 Label slow; // Fallthrough label. 7278 Label slow; // Fallthrough label.
7207 // Equality is almost reflexive (everything but NaN), so start by testing 7279 // Equality is almost reflexive (everything but NaN), so start by testing
7208 // for "identity and not NaN". 7280 // for "identity and not NaN".
(...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after
8776 } 8848 }
8777 break; 8849 break;
8778 } 8850 }
8779 default: UNREACHABLE(); break; 8851 default: UNREACHABLE(); break;
8780 } 8852 }
8781 8853
8782 // If all else fails, use the runtime system to get the correct 8854 // If all else fails, use the runtime system to get the correct
8783 // result. If arguments was passed in registers now place them on the 8855 // result. If arguments was passed in registers now place them on the
8784 // stack in the correct order below the return address. 8856 // stack in the correct order below the return address.
8785 __ bind(&call_runtime); 8857 __ bind(&call_runtime);
8858
8786 if (HasArgsInRegisters()) { 8859 if (HasArgsInRegisters()) {
8787 __ pop(rcx); 8860 __ pop(rcx);
8788 if (HasArgsReversed()) { 8861 if (HasArgsReversed()) {
8789 __ push(rax); 8862 __ push(rax);
8790 __ push(rdx); 8863 __ push(rdx);
8791 } else { 8864 } else {
8792 __ push(rdx); 8865 __ push(rdx);
8793 __ push(rax); 8866 __ push(rax);
8794 } 8867 }
8795 __ push(rcx); 8868 __ push(rcx);
8796 } 8869 }
8870
8797 switch (op_) { 8871 switch (op_) {
8798 case Token::ADD: { 8872 case Token::ADD: {
8873 // Registers containing left and right operands respectively.
8874 Register lhs, rhs;
8875
8876 if (HasArgsReversed()) {
8877 lhs = rax;
8878 rhs = rdx;
8879 } else {
8880 lhs = rdx;
8881 rhs = rax;
8882 }
8883
8799 // Test for string arguments before calling runtime. 8884 // Test for string arguments before calling runtime.
8800 Label not_strings, both_strings, not_string1, string1; 8885 Label not_strings, both_strings, not_string1, string1, string1_smi2;
8801 Condition is_smi; 8886 Condition is_smi;
8802 Result answer; 8887 Result answer;
8803 is_smi = masm->CheckSmi(rdx); 8888 is_smi = masm->CheckSmi(lhs);
8804 __ j(is_smi, &not_string1); 8889 __ j(is_smi, &not_string1);
8805 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rdx); 8890 __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, r8);
8806 __ j(above_equal, &not_string1); 8891 __ j(above_equal, &not_string1);
8807 8892
8808 // First argument is a a string, test second. 8893 // First argument is a a string, test second.
8809 is_smi = masm->CheckSmi(rax); 8894 is_smi = masm->CheckSmi(rhs);
8810 __ j(is_smi, &string1); 8895 __ j(is_smi, &string1_smi2);
8811 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax); 8896 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, r9);
8812 __ j(above_equal, &string1); 8897 __ j(above_equal, &string1);
8813 8898
8814 // First and second argument are strings. 8899 // First and second argument are strings.
8815 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 8900 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
8816 __ TailCallStub(&stub); 8901 __ TailCallStub(&string_add_stub);
8902
8903 __ bind(&string1_smi2);
8904 // First argument is a string, second is a smi. Try to lookup the number
8905 // string for the smi in the number string cache.
8906 NumberToStringStub::GenerateLookupNumberStringCache(
8907 masm, rhs, rbx, rcx, r8, true, &string1);
8908
8909 // Replace second argument on stack and tailcall string add stub to make
8910 // the result.
8911 __ movq(Operand(rsp, 1 * kPointerSize), rbx);
8912 __ TailCallStub(&string_add_stub);
8817 8913
8818 // Only first argument is a string. 8914 // Only first argument is a string.
8819 __ bind(&string1); 8915 __ bind(&string1);
8820 __ InvokeBuiltin( 8916 __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION);
8821 HasArgsReversed() ?
8822 Builtins::STRING_ADD_RIGHT :
8823 Builtins::STRING_ADD_LEFT,
8824 JUMP_FUNCTION);
8825 8917
8826 // First argument was not a string, test second. 8918 // First argument was not a string, test second.
8827 __ bind(&not_string1); 8919 __ bind(&not_string1);
8828 is_smi = masm->CheckSmi(rax); 8920 is_smi = masm->CheckSmi(rhs);
8829 __ j(is_smi, &not_strings); 8921 __ j(is_smi, &not_strings);
8830 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax); 8922 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, rhs);
8831 __ j(above_equal, &not_strings); 8923 __ j(above_equal, &not_strings);
8832 8924
8833 // Only second argument is a string. 8925 // Only second argument is a string.
8834 __ InvokeBuiltin( 8926 __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION);
8835 HasArgsReversed() ?
8836 Builtins::STRING_ADD_LEFT :
8837 Builtins::STRING_ADD_RIGHT,
8838 JUMP_FUNCTION);
8839 8927
8840 __ bind(&not_strings); 8928 __ bind(&not_strings);
8841 // Neither argument is a string. 8929 // Neither argument is a string.
8842 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); 8930 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
8843 break; 8931 break;
8844 } 8932 }
8845 case Token::SUB: 8933 case Token::SUB:
8846 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); 8934 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
8847 break; 8935 break;
8848 case Token::MUL: 8936 case Token::MUL:
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
9558 // Call the function from C++. 9646 // Call the function from C++.
9559 return FUNCTION_CAST<ModuloFunction>(buffer); 9647 return FUNCTION_CAST<ModuloFunction>(buffer);
9560 } 9648 }
9561 9649
9562 #endif 9650 #endif
9563 9651
9564 9652
9565 #undef __ 9653 #undef __
9566 9654
9567 } } // namespace v8::internal 9655 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698