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

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

Issue 22670004: Fix/unify root handling in code generation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3938 matching lines...) Expand 10 before | Expand all | Expand 10 after
3949 Register result, 3949 Register result,
3950 Register scratch1, 3950 Register scratch1,
3951 Register scratch2, 3951 Register scratch2,
3952 Label* not_found) { 3952 Label* not_found) {
3953 // Use of registers. Register result is used as a temporary. 3953 // Use of registers. Register result is used as a temporary.
3954 Register number_string_cache = result; 3954 Register number_string_cache = result;
3955 Register mask = scratch1; 3955 Register mask = scratch1;
3956 Register scratch = scratch2; 3956 Register scratch = scratch2;
3957 3957
3958 // Load the number string cache. 3958 // Load the number string cache.
3959 ExternalReference roots_array_start = 3959 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
3960 ExternalReference::roots_array_start(masm->isolate());
3961 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
3962 __ mov(number_string_cache,
3963 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
3964 // Make the hash mask from the length of the number string cache. It 3960 // Make the hash mask from the length of the number string cache. It
3965 // contains two elements (number and string) for each cache entry. 3961 // contains two elements (number and string) for each cache entry.
3966 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 3962 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
3967 __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. 3963 __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two.
3968 __ sub(mask, Immediate(1)); // Make mask. 3964 __ sub(mask, Immediate(1)); // Make mask.
3969 3965
3970 // Calculate the entry in the number string cache. The hash value in the 3966 // Calculate the entry in the number string cache. The hash value in the
3971 // number string cache for smis is just the smi value, and the hash for 3967 // number string cache for smis is just the smi value, and the hash for
3972 // doubles is the xor of the upper and lower words. See 3968 // doubles is the xor of the upper and lower words. See
3973 // Heap::GetNumberStringCache. 3969 // Heap::GetNumberStringCache.
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after
5003 Register scratch = ecx; 4999 Register scratch = ecx;
5004 5000
5005 // Constants describing the call site code to patch. 5001 // Constants describing the call site code to patch.
5006 static const int kDeltaToCmpImmediate = 2; 5002 static const int kDeltaToCmpImmediate = 2;
5007 static const int kDeltaToMov = 8; 5003 static const int kDeltaToMov = 8;
5008 static const int kDeltaToMovImmediate = 9; 5004 static const int kDeltaToMovImmediate = 9;
5009 static const int8_t kCmpEdiOperandByte1 = BitCast<int8_t, uint8_t>(0x3b); 5005 static const int8_t kCmpEdiOperandByte1 = BitCast<int8_t, uint8_t>(0x3b);
5010 static const int8_t kCmpEdiOperandByte2 = BitCast<int8_t, uint8_t>(0x3d); 5006 static const int8_t kCmpEdiOperandByte2 = BitCast<int8_t, uint8_t>(0x3d);
5011 static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8); 5007 static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8);
5012 5008
5013 ExternalReference roots_array_start =
5014 ExternalReference::roots_array_start(masm->isolate());
5015
5016 ASSERT_EQ(object.code(), InstanceofStub::left().code()); 5009 ASSERT_EQ(object.code(), InstanceofStub::left().code());
5017 ASSERT_EQ(function.code(), InstanceofStub::right().code()); 5010 ASSERT_EQ(function.code(), InstanceofStub::right().code());
5018 5011
5019 // Get the object and function - they are always both needed. 5012 // Get the object and function - they are always both needed.
5020 Label slow, not_js_object; 5013 Label slow, not_js_object;
5021 if (!HasArgsInRegisters()) { 5014 if (!HasArgsInRegisters()) {
5022 __ mov(object, Operand(esp, 2 * kPointerSize)); 5015 __ mov(object, Operand(esp, 2 * kPointerSize));
5023 __ mov(function, Operand(esp, 1 * kPointerSize)); 5016 __ mov(function, Operand(esp, 1 * kPointerSize));
5024 } 5017 }
5025 5018
5026 // Check that the left hand is a JS object. 5019 // Check that the left hand is a JS object.
5027 __ JumpIfSmi(object, &not_js_object); 5020 __ JumpIfSmi(object, &not_js_object);
5028 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 5021 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
5029 5022
5030 // If there is a call site cache don't look in the global cache, but do the 5023 // If there is a call site cache don't look in the global cache, but do the
5031 // real lookup and update the call site cache. 5024 // real lookup and update the call site cache.
5032 if (!HasCallSiteInlineCheck()) { 5025 if (!HasCallSiteInlineCheck()) {
5033 // Look up the function and the map in the instanceof cache. 5026 // Look up the function and the map in the instanceof cache.
5034 Label miss; 5027 Label miss;
5035 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex)); 5028 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
5036 __ cmp(function, Operand::StaticArray(scratch,
5037 times_pointer_size,
5038 roots_array_start));
5039 __ j(not_equal, &miss, Label::kNear); 5029 __ j(not_equal, &miss, Label::kNear);
5040 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 5030 __ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex);
5041 __ cmp(map, Operand::StaticArray(
5042 scratch, times_pointer_size, roots_array_start));
5043 __ j(not_equal, &miss, Label::kNear); 5031 __ j(not_equal, &miss, Label::kNear);
5044 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 5032 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex);
5045 __ mov(eax, Operand::StaticArray(
5046 scratch, times_pointer_size, roots_array_start));
5047 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 5033 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
5048 __ bind(&miss); 5034 __ bind(&miss);
5049 } 5035 }
5050 5036
5051 // Get the prototype of the function. 5037 // Get the prototype of the function.
5052 __ TryGetFunctionPrototype(function, prototype, scratch, &slow, true); 5038 __ TryGetFunctionPrototype(function, prototype, scratch, &slow, true);
5053 5039
5054 // Check that the function prototype is a JS object. 5040 // Check that the function prototype is a JS object.
5055 __ JumpIfSmi(prototype, &slow); 5041 __ JumpIfSmi(prototype, &slow);
5056 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow); 5042 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
5057 5043
5058 // Update the global instanceof or call site inlined cache with the current 5044 // Update the global instanceof or call site inlined cache with the current
5059 // map and function. The cached answer will be set when it is known below. 5045 // map and function. The cached answer will be set when it is known below.
5060 if (!HasCallSiteInlineCheck()) { 5046 if (!HasCallSiteInlineCheck()) {
5061 __ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex)); 5047 __ StoreRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex);
5062 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start), 5048 __ StoreRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
5063 map);
5064 __ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
5065 __ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
5066 function);
5067 } else { 5049 } else {
5068 // The constants for the code patching are based on no push instructions 5050 // The constants for the code patching are based on no push instructions
5069 // at the call site. 5051 // at the call site.
5070 ASSERT(HasArgsInRegisters()); 5052 ASSERT(HasArgsInRegisters());
5071 // Get return address and delta to inlined map check. 5053 // Get return address and delta to inlined map check.
5072 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5054 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5073 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5055 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5074 if (FLAG_debug_code) { 5056 if (FLAG_debug_code) {
5075 __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1); 5057 __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1);
5076 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCmp1); 5058 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCmp1);
(...skipping 13 matching lines...) Expand all
5090 __ j(equal, &is_instance, Label::kNear); 5072 __ j(equal, &is_instance, Label::kNear);
5091 Factory* factory = masm->isolate()->factory(); 5073 Factory* factory = masm->isolate()->factory();
5092 __ cmp(scratch, Immediate(factory->null_value())); 5074 __ cmp(scratch, Immediate(factory->null_value()));
5093 __ j(equal, &is_not_instance, Label::kNear); 5075 __ j(equal, &is_not_instance, Label::kNear);
5094 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 5076 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
5095 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); 5077 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
5096 __ jmp(&loop); 5078 __ jmp(&loop);
5097 5079
5098 __ bind(&is_instance); 5080 __ bind(&is_instance);
5099 if (!HasCallSiteInlineCheck()) { 5081 if (!HasCallSiteInlineCheck()) {
5100 __ Set(eax, Immediate(0)); 5082 __ mov(eax, Immediate(0));
5101 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 5083 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
5102 __ mov(Operand::StaticArray(scratch,
5103 times_pointer_size, roots_array_start), eax);
5104 } else { 5084 } else {
5105 // Get return address and delta to inlined map check. 5085 // Get return address and delta to inlined map check.
5106 __ mov(eax, factory->true_value()); 5086 __ mov(eax, factory->true_value());
5107 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5087 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5108 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5088 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5109 if (FLAG_debug_code) { 5089 if (FLAG_debug_code) {
5110 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 5090 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
5111 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 5091 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
5112 } 5092 }
5113 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 5093 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
5114 if (!ReturnTrueFalseObject()) { 5094 if (!ReturnTrueFalseObject()) {
5115 __ Set(eax, Immediate(0)); 5095 __ Set(eax, Immediate(0));
5116 } 5096 }
5117 } 5097 }
5118 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 5098 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
5119 5099
5120 __ bind(&is_not_instance); 5100 __ bind(&is_not_instance);
5121 if (!HasCallSiteInlineCheck()) { 5101 if (!HasCallSiteInlineCheck()) {
5122 __ Set(eax, Immediate(Smi::FromInt(1))); 5102 __ mov(eax, Immediate(Smi::FromInt(1)));
5123 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 5103 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
5124 __ mov(Operand::StaticArray(
5125 scratch, times_pointer_size, roots_array_start), eax);
5126 } else { 5104 } else {
5127 // Get return address and delta to inlined map check. 5105 // Get return address and delta to inlined map check.
5128 __ mov(eax, factory->false_value()); 5106 __ mov(eax, factory->false_value());
5129 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5107 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5130 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5108 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5131 if (FLAG_debug_code) { 5109 if (FLAG_debug_code) {
5132 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 5110 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
5133 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 5111 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
5134 } 5112 }
5135 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 5113 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
5868 // Collect the two characters in a register. 5846 // Collect the two characters in a register.
5869 Register chars = c1; 5847 Register chars = c1;
5870 __ shl(c2, kBitsPerByte); 5848 __ shl(c2, kBitsPerByte);
5871 __ or_(chars, c2); 5849 __ or_(chars, c2);
5872 5850
5873 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5851 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5874 // hash: hash of two character string. 5852 // hash: hash of two character string.
5875 5853
5876 // Load the string table. 5854 // Load the string table.
5877 Register string_table = c2; 5855 Register string_table = c2;
5878 ExternalReference roots_array_start = 5856 __ LoadRoot(string_table, Heap::kStringTableRootIndex);
5879 ExternalReference::roots_array_start(masm->isolate());
5880 __ mov(scratch, Immediate(Heap::kStringTableRootIndex));
5881 __ mov(string_table,
5882 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
5883 5857
5884 // Calculate capacity mask from the string table capacity. 5858 // Calculate capacity mask from the string table capacity.
5885 Register mask = scratch2; 5859 Register mask = scratch2;
5886 __ mov(mask, FieldOperand(string_table, StringTable::kCapacityOffset)); 5860 __ mov(mask, FieldOperand(string_table, StringTable::kCapacityOffset));
5887 __ SmiUntag(mask); 5861 __ SmiUntag(mask);
5888 __ sub(mask, Immediate(1)); 5862 __ sub(mask, Immediate(1));
5889 5863
5890 // Registers 5864 // Registers
5891 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5865 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5892 // hash: hash of two character string 5866 // hash: hash of two character string
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
5960 } 5934 }
5961 } 5935 }
5962 5936
5963 5937
5964 void StringHelper::GenerateHashInit(MacroAssembler* masm, 5938 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5965 Register hash, 5939 Register hash,
5966 Register character, 5940 Register character,
5967 Register scratch) { 5941 Register scratch) {
5968 // hash = (seed + character) + ((seed + character) << 10); 5942 // hash = (seed + character) + ((seed + character) << 10);
5969 if (Serializer::enabled()) { 5943 if (Serializer::enabled()) {
5970 ExternalReference roots_array_start = 5944 __ LoadRoot(scratch, Heap::kHashSeedRootIndex);
5971 ExternalReference::roots_array_start(masm->isolate());
5972 __ mov(scratch, Immediate(Heap::kHashSeedRootIndex));
5973 __ mov(scratch, Operand::StaticArray(scratch,
5974 times_pointer_size,
5975 roots_array_start));
5976 __ SmiUntag(scratch); 5945 __ SmiUntag(scratch);
5977 __ add(scratch, character); 5946 __ add(scratch, character);
5978 __ mov(hash, scratch); 5947 __ mov(hash, scratch);
5979 __ shl(scratch, 10); 5948 __ shl(scratch, 10);
5980 __ add(hash, scratch); 5949 __ add(hash, scratch);
5981 } else { 5950 } else {
5982 int32_t seed = masm->isolate()->heap()->HashSeed(); 5951 int32_t seed = masm->isolate()->heap()->HashSeed();
5983 __ lea(scratch, Operand(character, seed)); 5952 __ lea(scratch, Operand(character, seed));
5984 __ shl(scratch, 10); 5953 __ shl(scratch, 10);
5985 __ lea(hash, Operand(scratch, character, times_1, seed)); 5954 __ lea(hash, Operand(scratch, character, times_1, seed));
(...skipping 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after
7745 __ bind(&fast_elements_case); 7714 __ bind(&fast_elements_case);
7746 GenerateCase(masm, FAST_ELEMENTS); 7715 GenerateCase(masm, FAST_ELEMENTS);
7747 } 7716 }
7748 7717
7749 7718
7750 #undef __ 7719 #undef __
7751 7720
7752 } } // namespace v8::internal 7721 } } // namespace v8::internal
7753 7722
7754 #endif // V8_TARGET_ARCH_IA32 7723 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | src/ia32/macro-assembler-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698