| 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 5609 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5620   Load(args->at(0)); | 5620   Load(args->at(0)); | 
| 5621   Load(args->at(1)); | 5621   Load(args->at(1)); | 
| 5622   Load(args->at(2)); | 5622   Load(args->at(2)); | 
| 5623   Load(args->at(3)); | 5623   Load(args->at(3)); | 
| 5624   RegExpExecStub stub; | 5624   RegExpExecStub stub; | 
| 5625   Result result = frame_->CallStub(&stub, 4); | 5625   Result result = frame_->CallStub(&stub, 4); | 
| 5626   frame_->Push(&result); | 5626   frame_->Push(&result); | 
| 5627 } | 5627 } | 
| 5628 | 5628 | 
| 5629 | 5629 | 
|  | 5630 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { | 
|  | 5631   ASSERT_EQ(args->length(), 1); | 
|  | 5632 | 
|  | 5633   // Load the argument on the stack and call the stub. | 
|  | 5634   Load(args->at(0)); | 
|  | 5635   NumberToStringStub stub; | 
|  | 5636   Result result = frame_->CallStub(&stub, 1); | 
|  | 5637   frame_->Push(&result); | 
|  | 5638 } | 
|  | 5639 | 
|  | 5640 | 
| 5630 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { | 5641 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { | 
| 5631   if (CheckForInlineRuntimeCall(node)) { | 5642   if (CheckForInlineRuntimeCall(node)) { | 
| 5632     return; | 5643     return; | 
| 5633   } | 5644   } | 
| 5634 | 5645 | 
| 5635   ZoneList<Expression*>* args = node->arguments(); | 5646   ZoneList<Expression*>* args = node->arguments(); | 
| 5636   Comment cmnt(masm_, "[ CallRuntime"); | 5647   Comment cmnt(masm_, "[ CallRuntime"); | 
| 5637   Runtime::Function* function = node->function(); | 5648   Runtime::Function* function = node->function(); | 
| 5638 | 5649 | 
| 5639   if (function == NULL) { | 5650   if (function == NULL) { | 
| (...skipping 2135 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7775       __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx); | 7786       __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx); | 
| 7776       __ j(above_equal, &string1); | 7787       __ j(above_equal, &string1); | 
| 7777 | 7788 | 
| 7778       // First and second argument are strings. Jump to the string add stub. | 7789       // First and second argument are strings. Jump to the string add stub. | 
| 7779       StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); | 7790       StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); | 
| 7780       __ TailCallStub(&string_add_stub); | 7791       __ TailCallStub(&string_add_stub); | 
| 7781 | 7792 | 
| 7782       __ bind(&string1_smi2); | 7793       __ bind(&string1_smi2); | 
| 7783       // First argument is a string, second is a smi. Try to lookup the number | 7794       // First argument is a string, second is a smi. Try to lookup the number | 
| 7784       // string for the smi in the number string cache. | 7795       // string for the smi in the number string cache. | 
| 7785       // Load the number string cache. | 7796       NumberToStringStub::GenerateLookupNumberStringCache( | 
| 7786       ExternalReference roots_address = ExternalReference::roots_address(); | 7797           masm, eax, edi, ebx, ecx, true, &string1); | 
| 7787       __ mov(ecx, Immediate(Heap::kNumberStringCacheRootIndex)); |  | 
| 7788       __ mov(ebx, |  | 
| 7789              Operand::StaticArray(ecx, times_pointer_size, roots_address)); |  | 
| 7790       // Make the hash mask from the length of the number string cache. It |  | 
| 7791       // contains two elements (number and string) for each cache entry. |  | 
| 7792       __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |  | 
| 7793       __ shr(ecx, 1);  // Divide length by two (length is not a smi). |  | 
| 7794       __ sub(Operand(ecx), Immediate(1));  // Make mask. |  | 
| 7795       // Calculate the entry in the number string cache. The hash value in the |  | 
| 7796       // number string cache for smis is just the smi value. |  | 
| 7797       __ mov(edi, eax); |  | 
| 7798       __ SmiUntag(edi); |  | 
| 7799       __ and_(edi, Operand(ecx)); |  | 
| 7800       // Check if the entry is the smi we are looking for. |  | 
| 7801       __ cmp(eax, |  | 
| 7802              FieldOperand(ebx, |  | 
| 7803                           edi, |  | 
| 7804                           times_twice_pointer_size, |  | 
| 7805                           FixedArray::kHeaderSize)); |  | 
| 7806       __ IncrementCounter(equal, &Counters::string_plus_smi_hit, 1); |  | 
| 7807       __ IncrementCounter(not_equal, &Counters::string_plus_smi_miss, 1); |  | 
| 7808       __ j(not_equal, &string1); |  | 
| 7809 | 7798 | 
| 7810       // Get the string from the cache and call the string add stub to make the | 7799       // Call the string add stub to make the result. | 
| 7811       // result. |  | 
| 7812       __ mov(edi, |  | 
| 7813              FieldOperand(ebx, |  | 
| 7814                           edi, |  | 
| 7815                           times_twice_pointer_size, |  | 
| 7816                           FixedArray::kHeaderSize + kPointerSize)); |  | 
| 7817       __ EnterInternalFrame(); | 7800       __ EnterInternalFrame(); | 
| 7818       __ push(edx);  // Original first argument. | 7801       __ push(edx);  // Original first argument. | 
| 7819       __ push(edi);  // Number to string result for second argument. | 7802       __ push(edi);  // Number to string result for second argument. | 
| 7820       __ CallStub(&string_add_stub); | 7803       __ CallStub(&string_add_stub); | 
| 7821       __ LeaveInternalFrame(); | 7804       __ LeaveInternalFrame(); | 
| 7822       __ ret(2 * kPointerSize); | 7805       __ ret(2 * kPointerSize); | 
| 7823 | 7806 | 
| 7824       __ bind(&string1); | 7807       __ bind(&string1); | 
| 7825       __ InvokeBuiltin( | 7808       __ InvokeBuiltin( | 
| 7826           HasArgsReversed() ? | 7809           HasArgsReversed() ? | 
| (...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 8944   __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 8927   __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 
| 8945   __ ret(4 * kPointerSize); | 8928   __ ret(4 * kPointerSize); | 
| 8946 | 8929 | 
| 8947   // Do the runtime call to execute the regexp. | 8930   // Do the runtime call to execute the regexp. | 
| 8948   __ bind(&runtime); | 8931   __ bind(&runtime); | 
| 8949   __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); | 8932   __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); | 
| 8950 #endif  // V8_NATIVE_REGEXP | 8933 #endif  // V8_NATIVE_REGEXP | 
| 8951 } | 8934 } | 
| 8952 | 8935 | 
| 8953 | 8936 | 
|  | 8937 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 
|  | 8938                                                          Register object, | 
|  | 8939                                                          Register result, | 
|  | 8940                                                          Register scratch1, | 
|  | 8941                                                          Register scratch2, | 
|  | 8942                                                          bool object_is_smi, | 
|  | 8943                                                          Label* not_found) { | 
|  | 8944   // Currently only lookup for smis. Check for smi if object is not known to be | 
|  | 8945   // a smi. | 
|  | 8946   if (!object_is_smi) { | 
|  | 8947     ASSERT(kSmiTag == 0); | 
|  | 8948     __ test(object, Immediate(kSmiTagMask)); | 
|  | 8949     __ j(not_zero, not_found); | 
|  | 8950   } | 
|  | 8951 | 
|  | 8952   // Use of registers. Register result is used as a temporary. | 
|  | 8953   Register number_string_cache = result; | 
|  | 8954   Register mask = scratch1; | 
|  | 8955   Register scratch = scratch2; | 
|  | 8956 | 
|  | 8957   // Load the number string cache. | 
|  | 8958   ExternalReference roots_address = ExternalReference::roots_address(); | 
|  | 8959   __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex)); | 
|  | 8960   __ mov(number_string_cache, | 
|  | 8961          Operand::StaticArray(scratch, times_pointer_size, roots_address)); | 
|  | 8962   // Make the hash mask from the length of the number string cache. It | 
|  | 8963   // contains two elements (number and string) for each cache entry. | 
|  | 8964   __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | 
|  | 8965   __ shr(mask, 1);  // Divide length by two (length is not a smi). | 
|  | 8966   __ sub(Operand(mask), Immediate(1));  // Make mask. | 
|  | 8967   // Calculate the entry in the number string cache. The hash value in the | 
|  | 8968   // number string cache for smis is just the smi value. | 
|  | 8969   __ mov(scratch, object); | 
|  | 8970   __ SmiUntag(scratch); | 
|  | 8971   __ and_(scratch, Operand(mask)); | 
|  | 8972   // Check if the entry is the smi we are looking for. | 
|  | 8973   __ cmp(object, | 
|  | 8974          FieldOperand(number_string_cache, | 
|  | 8975                       scratch, | 
|  | 8976                       times_twice_pointer_size, | 
|  | 8977                       FixedArray::kHeaderSize)); | 
|  | 8978   __ j(not_equal, not_found); | 
|  | 8979 | 
|  | 8980   // Get the result from the cache. | 
|  | 8981   __ mov(result, | 
|  | 8982          FieldOperand(number_string_cache, | 
|  | 8983                       scratch, | 
|  | 8984                       times_twice_pointer_size, | 
|  | 8985                       FixedArray::kHeaderSize + kPointerSize)); | 
|  | 8986   __ IncrementCounter(&Counters::number_to_string_native, 1); | 
|  | 8987 } | 
|  | 8988 | 
|  | 8989 | 
|  | 8990 void NumberToStringStub::Generate(MacroAssembler* masm) { | 
|  | 8991   Label runtime; | 
|  | 8992 | 
|  | 8993   __ mov(ebx, Operand(esp, kPointerSize)); | 
|  | 8994 | 
|  | 8995   // Generate code to lookup number in the number string cache. | 
|  | 8996   GenerateLookupNumberStringCache(masm, ebx, eax, ebx, ecx, false, &runtime); | 
|  | 8997   __ ret(1 * kPointerSize); | 
|  | 8998 | 
|  | 8999   __ bind(&runtime); | 
|  | 9000   // Handle number to string in the runtime system if not found in the cache. | 
|  | 9001   __ TailCallRuntime(ExternalReference(Runtime::kNumberToString), 1, 1); | 
|  | 9002 } | 
|  | 9003 | 
|  | 9004 | 
| 8954 void CompareStub::Generate(MacroAssembler* masm) { | 9005 void CompareStub::Generate(MacroAssembler* masm) { | 
| 8955   Label call_builtin, done; | 9006   Label call_builtin, done; | 
| 8956 | 9007 | 
| 8957   // NOTICE! This code is only reached after a smi-fast-case check, so | 9008   // NOTICE! This code is only reached after a smi-fast-case check, so | 
| 8958   // it is certain that at least one operand isn't a smi. | 9009   // it is certain that at least one operand isn't a smi. | 
| 8959 | 9010 | 
| 8960   if (cc_ == equal) {  // Both strict and non-strict. | 9011   if (cc_ == equal) {  // Both strict and non-strict. | 
| 8961     Label slow;  // Fallthrough label. | 9012     Label slow;  // Fallthrough label. | 
| 8962     // Equality is almost reflexive (everything but NaN), so start by testing | 9013     // Equality is almost reflexive (everything but NaN), so start by testing | 
| 8963     // for "identity and not NaN". | 9014     // for "identity and not NaN". | 
| (...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 10546 | 10597 | 
| 10547   // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10598   // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 
| 10548   // tagged as a small integer. | 10599   // tagged as a small integer. | 
| 10549   __ bind(&runtime); | 10600   __ bind(&runtime); | 
| 10550   __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10601   __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 
| 10551 } | 10602 } | 
| 10552 | 10603 | 
| 10553 #undef __ | 10604 #undef __ | 
| 10554 | 10605 | 
| 10555 } }  // namespace v8::internal | 10606 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|