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

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

Issue 8344079: Shave 39% from snapshot size. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 2 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/heap.h ('k') | src/ia32/macro-assembler-ia32.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3864 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 Register scratch1, 3875 Register scratch1,
3876 Register scratch2, 3876 Register scratch2,
3877 bool object_is_smi, 3877 bool object_is_smi,
3878 Label* not_found) { 3878 Label* not_found) {
3879 // Use of registers. Register result is used as a temporary. 3879 // Use of registers. Register result is used as a temporary.
3880 Register number_string_cache = result; 3880 Register number_string_cache = result;
3881 Register mask = scratch1; 3881 Register mask = scratch1;
3882 Register scratch = scratch2; 3882 Register scratch = scratch2;
3883 3883
3884 // Load the number string cache. 3884 // Load the number string cache.
3885 ExternalReference roots_address = 3885 ExternalReference roots_array_start =
3886 ExternalReference::roots_address(masm->isolate()); 3886 ExternalReference::roots_array_start(masm->isolate());
3887 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex)); 3887 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
3888 __ mov(number_string_cache, 3888 __ mov(number_string_cache,
3889 Operand::StaticArray(scratch, times_pointer_size, roots_address)); 3889 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
3890 // Make the hash mask from the length of the number string cache. It 3890 // Make the hash mask from the length of the number string cache. It
3891 // contains two elements (number and string) for each cache entry. 3891 // contains two elements (number and string) for each cache entry.
3892 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 3892 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
3893 __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. 3893 __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two.
3894 __ sub(mask, Immediate(1)); // Make mask. 3894 __ sub(mask, Immediate(1)); // Make mask.
3895 3895
3896 // Calculate the entry in the number string cache. The hash value in the 3896 // Calculate the entry in the number string cache. The hash value in the
3897 // number string cache for smis is just the smi value, and the hash for 3897 // number string cache for smis is just the smi value, and the hash for
3898 // doubles is the xor of the upper and lower words. See 3898 // doubles is the xor of the upper and lower words. See
3899 // Heap::GetNumberStringCache. 3899 // Heap::GetNumberStringCache.
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
4847 Register scratch = ecx; 4847 Register scratch = ecx;
4848 4848
4849 // Constants describing the call site code to patch. 4849 // Constants describing the call site code to patch.
4850 static const int kDeltaToCmpImmediate = 2; 4850 static const int kDeltaToCmpImmediate = 2;
4851 static const int kDeltaToMov = 8; 4851 static const int kDeltaToMov = 8;
4852 static const int kDeltaToMovImmediate = 9; 4852 static const int kDeltaToMovImmediate = 9;
4853 static const int8_t kCmpEdiImmediateByte1 = BitCast<int8_t, uint8_t>(0x81); 4853 static const int8_t kCmpEdiImmediateByte1 = BitCast<int8_t, uint8_t>(0x81);
4854 static const int8_t kCmpEdiImmediateByte2 = BitCast<int8_t, uint8_t>(0xff); 4854 static const int8_t kCmpEdiImmediateByte2 = BitCast<int8_t, uint8_t>(0xff);
4855 static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8); 4855 static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8);
4856 4856
4857 ExternalReference roots_address = 4857 ExternalReference roots_array_start =
4858 ExternalReference::roots_address(masm->isolate()); 4858 ExternalReference::roots_array_start(masm->isolate());
4859 4859
4860 ASSERT_EQ(object.code(), InstanceofStub::left().code()); 4860 ASSERT_EQ(object.code(), InstanceofStub::left().code());
4861 ASSERT_EQ(function.code(), InstanceofStub::right().code()); 4861 ASSERT_EQ(function.code(), InstanceofStub::right().code());
4862 4862
4863 // Get the object and function - they are always both needed. 4863 // Get the object and function - they are always both needed.
4864 Label slow, not_js_object; 4864 Label slow, not_js_object;
4865 if (!HasArgsInRegisters()) { 4865 if (!HasArgsInRegisters()) {
4866 __ mov(object, Operand(esp, 2 * kPointerSize)); 4866 __ mov(object, Operand(esp, 2 * kPointerSize));
4867 __ mov(function, Operand(esp, 1 * kPointerSize)); 4867 __ mov(function, Operand(esp, 1 * kPointerSize));
4868 } 4868 }
4869 4869
4870 // Check that the left hand is a JS object. 4870 // Check that the left hand is a JS object.
4871 __ JumpIfSmi(object, &not_js_object); 4871 __ JumpIfSmi(object, &not_js_object);
4872 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 4872 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
4873 4873
4874 // If there is a call site cache don't look in the global cache, but do the 4874 // If there is a call site cache don't look in the global cache, but do the
4875 // real lookup and update the call site cache. 4875 // real lookup and update the call site cache.
4876 if (!HasCallSiteInlineCheck()) { 4876 if (!HasCallSiteInlineCheck()) {
4877 // Look up the function and the map in the instanceof cache. 4877 // Look up the function and the map in the instanceof cache.
4878 Label miss; 4878 Label miss;
4879 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 4879 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
4880 __ cmp(function, 4880 __ cmp(function, Operand::StaticArray(scratch,
4881 Operand::StaticArray(scratch, times_pointer_size, roots_address)); 4881 times_pointer_size,
4882 roots_array_start));
4882 __ j(not_equal, &miss, Label::kNear); 4883 __ j(not_equal, &miss, Label::kNear);
4883 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 4884 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
4884 __ cmp(map, Operand::StaticArray( 4885 __ cmp(map, Operand::StaticArray(
4885 scratch, times_pointer_size, roots_address)); 4886 scratch, times_pointer_size, roots_array_start));
4886 __ j(not_equal, &miss, Label::kNear); 4887 __ j(not_equal, &miss, Label::kNear);
4887 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 4888 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
4888 __ mov(eax, Operand::StaticArray( 4889 __ mov(eax, Operand::StaticArray(
4889 scratch, times_pointer_size, roots_address)); 4890 scratch, times_pointer_size, roots_array_start));
4890 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4891 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4891 __ bind(&miss); 4892 __ bind(&miss);
4892 } 4893 }
4893 4894
4894 // Get the prototype of the function. 4895 // Get the prototype of the function.
4895 __ TryGetFunctionPrototype(function, prototype, scratch, &slow, true); 4896 __ TryGetFunctionPrototype(function, prototype, scratch, &slow, true);
4896 4897
4897 // Check that the function prototype is a JS object. 4898 // Check that the function prototype is a JS object.
4898 __ JumpIfSmi(prototype, &slow); 4899 __ JumpIfSmi(prototype, &slow);
4899 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow); 4900 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
4900 4901
4901 // Update the global instanceof or call site inlined cache with the current 4902 // Update the global instanceof or call site inlined cache with the current
4902 // map and function. The cached answer will be set when it is known below. 4903 // map and function. The cached answer will be set when it is known below.
4903 if (!HasCallSiteInlineCheck()) { 4904 if (!HasCallSiteInlineCheck()) {
4904 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 4905 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
4905 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address), map); 4906 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
4907 map);
4906 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 4908 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
4907 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_address), 4909 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
4908 function); 4910 function);
4909 } else { 4911 } else {
4910 // The constants for the code patching are based on no push instructions 4912 // The constants for the code patching are based on no push instructions
4911 // at the call site. 4913 // at the call site.
4912 ASSERT(HasArgsInRegisters()); 4914 ASSERT(HasArgsInRegisters());
4913 // Get return address and delta to inlined map check. 4915 // Get return address and delta to inlined map check.
4914 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 4916 __ mov(scratch, Operand(esp, 0 * kPointerSize));
4915 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 4917 __ sub(scratch, Operand(esp, 1 * kPointerSize));
4916 if (FLAG_debug_code) { 4918 if (FLAG_debug_code) {
4917 __ cmpb(Operand(scratch, 0), kCmpEdiImmediateByte1); 4919 __ cmpb(Operand(scratch, 0), kCmpEdiImmediateByte1);
(...skipping 16 matching lines...) Expand all
4934 __ j(equal, &is_not_instance, Label::kNear); 4936 __ j(equal, &is_not_instance, Label::kNear);
4935 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 4937 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
4936 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); 4938 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
4937 __ jmp(&loop); 4939 __ jmp(&loop);
4938 4940
4939 __ bind(&is_instance); 4941 __ bind(&is_instance);
4940 if (!HasCallSiteInlineCheck()) { 4942 if (!HasCallSiteInlineCheck()) {
4941 __ Set(eax, Immediate(0)); 4943 __ Set(eax, Immediate(0));
4942 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 4944 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
4943 __ mov(Operand::StaticArray(scratch, 4945 __ mov(Operand::StaticArray(scratch,
4944 times_pointer_size, roots_address), eax); 4946 times_pointer_size, roots_array_start), eax);
4945 } else { 4947 } else {
4946 // Get return address and delta to inlined map check. 4948 // Get return address and delta to inlined map check.
4947 __ mov(eax, factory->true_value()); 4949 __ mov(eax, factory->true_value());
4948 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 4950 __ mov(scratch, Operand(esp, 0 * kPointerSize));
4949 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 4951 __ sub(scratch, Operand(esp, 1 * kPointerSize));
4950 if (FLAG_debug_code) { 4952 if (FLAG_debug_code) {
4951 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 4953 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
4952 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)"); 4954 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
4953 } 4955 }
4954 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 4956 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
4955 if (!ReturnTrueFalseObject()) { 4957 if (!ReturnTrueFalseObject()) {
4956 __ Set(eax, Immediate(0)); 4958 __ Set(eax, Immediate(0));
4957 } 4959 }
4958 } 4960 }
4959 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 4961 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
4960 4962
4961 __ bind(&is_not_instance); 4963 __ bind(&is_not_instance);
4962 if (!HasCallSiteInlineCheck()) { 4964 if (!HasCallSiteInlineCheck()) {
4963 __ Set(eax, Immediate(Smi::FromInt(1))); 4965 __ Set(eax, Immediate(Smi::FromInt(1)));
4964 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 4966 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
4965 __ mov(Operand::StaticArray( 4967 __ mov(Operand::StaticArray(
4966 scratch, times_pointer_size, roots_address), eax); 4968 scratch, times_pointer_size, roots_array_start), eax);
4967 } else { 4969 } else {
4968 // Get return address and delta to inlined map check. 4970 // Get return address and delta to inlined map check.
4969 __ mov(eax, factory->false_value()); 4971 __ mov(eax, factory->false_value());
4970 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 4972 __ mov(scratch, Operand(esp, 0 * kPointerSize));
4971 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 4973 __ sub(scratch, Operand(esp, 1 * kPointerSize));
4972 if (FLAG_debug_code) { 4974 if (FLAG_debug_code) {
4973 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 4975 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
4974 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)"); 4976 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
4975 } 4977 }
4976 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 4978 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
5745 // Collect the two characters in a register. 5747 // Collect the two characters in a register.
5746 Register chars = c1; 5748 Register chars = c1;
5747 __ shl(c2, kBitsPerByte); 5749 __ shl(c2, kBitsPerByte);
5748 __ or_(chars, c2); 5750 __ or_(chars, c2);
5749 5751
5750 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5752 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5751 // hash: hash of two character string. 5753 // hash: hash of two character string.
5752 5754
5753 // Load the symbol table. 5755 // Load the symbol table.
5754 Register symbol_table = c2; 5756 Register symbol_table = c2;
5755 ExternalReference roots_address = 5757 ExternalReference roots_array_start =
5756 ExternalReference::roots_address(masm->isolate()); 5758 ExternalReference::roots_array_start(masm->isolate());
5757 __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex)); 5759 __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex));
5758 __ mov(symbol_table, 5760 __ mov(symbol_table,
5759 Operand::StaticArray(scratch, times_pointer_size, roots_address)); 5761 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
5760 5762
5761 // Calculate capacity mask from the symbol table capacity. 5763 // Calculate capacity mask from the symbol table capacity.
5762 Register mask = scratch2; 5764 Register mask = scratch2;
5763 __ mov(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); 5765 __ mov(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset));
5764 __ SmiUntag(mask); 5766 __ SmiUntag(mask);
5765 __ sub(mask, Immediate(1)); 5767 __ sub(mask, Immediate(1));
5766 5768
5767 // Registers 5769 // Registers
5768 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5770 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5769 // hash: hash of two character string 5771 // hash: hash of two character string
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
7270 // Restore registers. 7272 // Restore registers.
7271 __ pop(eax); 7273 __ pop(eax);
7272 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 7274 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
7273 } 7275 }
7274 7276
7275 #undef __ 7277 #undef __
7276 7278
7277 } } // namespace v8::internal 7279 } } // namespace v8::internal
7278 7280
7279 #endif // V8_TARGET_ARCH_IA32 7281 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698