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

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

Issue 604062: Inline NumberToString... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 10 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/ia32/codegen-ia32.h ('k') | src/runtime.js » ('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 5609 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698