| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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, ¬_string1); | 8889       __ j(is_smi, ¬_string1); | 
| 8805       __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rdx); | 8890       __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, r8); | 
| 8806       __ j(above_equal, ¬_string1); | 8891       __ j(above_equal, ¬_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(¬_string1); | 8919       __ bind(¬_string1); | 
| 8828       is_smi = masm->CheckSmi(rax); | 8920       is_smi = masm->CheckSmi(rhs); | 
| 8829       __ j(is_smi, ¬_strings); | 8921       __ j(is_smi, ¬_strings); | 
| 8830       __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax); | 8922       __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, rhs); | 
| 8831       __ j(above_equal, ¬_strings); | 8923       __ j(above_equal, ¬_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(¬_strings); | 8928       __ bind(¬_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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|