From c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7a Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Wed, 8 Mar 2017 14:04:23 +0000 Subject: Merge V8 5.6.326.50 Test: manual, ran D8, tested connecting through PAC proxy. Change-Id: I6067097f8ded999e9930a7dfd2fdc3733d7c6284 --- src/ic/x87/ic-x87.cc | 244 --------------------------------------------------- 1 file changed, 244 deletions(-) (limited to 'src/ic/x87/ic-x87.cc') diff --git a/src/ic/x87/ic-x87.cc b/src/ic/x87/ic-x87.cc index baf435e0..f96e509f 100644 --- a/src/ic/x87/ic-x87.cc +++ b/src/ic/x87/ic-x87.cc @@ -18,18 +18,6 @@ namespace internal { #define __ ACCESS_MASM(masm) - -static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type, - Label* global_object) { - // Register usage: - // type: holds the receiver instance type on entry. - __ cmp(type, JS_GLOBAL_OBJECT_TYPE); - __ j(equal, global_object); - __ cmp(type, JS_GLOBAL_PROXY_TYPE); - __ j(equal, global_object); -} - - // Helper function used to load a property from a dictionary backing // storage. This function may fail to load a property even though it is // in the dictionary, so code at miss_label must always call a backup @@ -132,238 +120,6 @@ static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label, __ RecordWrite(elements, r0, r1, kDontSaveFPRegs); } - -// Checks the receiver for special cases (value type, slow case bits). -// Falls through for regular JS object. -static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm, - Register receiver, Register map, - int interceptor_bit, Label* slow) { - // Register use: - // receiver - holds the receiver and is unchanged. - // Scratch registers: - // map - used to hold the map of the receiver. - - // Check that the object isn't a smi. - __ JumpIfSmi(receiver, slow); - - // Get the map of the receiver. - __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); - - // Check bit field. - __ test_b( - FieldOperand(map, Map::kBitFieldOffset), - Immediate((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); - __ j(not_zero, slow); - // Check that the object is some kind of JS object EXCEPT JS Value type. In - // the case that the object is a value-wrapper object, we enter the runtime - // system to make sure that indexing into string objects works as intended. - DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); - - __ CmpInstanceType(map, JS_OBJECT_TYPE); - __ j(below, slow); -} - - -// Loads an indexed element from a fast case array. -static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, - Register key, Register scratch, - Register scratch2, Register result, - Label* slow) { - // Register use: - // receiver - holds the receiver and is unchanged. - // key - holds the key and is unchanged (must be a smi). - // Scratch registers: - // scratch - used to hold elements of the receiver and the loaded value. - // scratch2 - holds maps and prototypes during prototype chain check. - // result - holds the result on exit if the load succeeds and - // we fall through. - Label check_prototypes, check_next_prototype; - Label done, in_bounds, absent; - - __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset)); - __ AssertFastElements(scratch); - - // Check that the key (index) is within bounds. - __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset)); - __ j(below, &in_bounds); - // Out-of-bounds. Check the prototype chain to see if we can just return - // 'undefined'. - __ cmp(key, 0); - __ j(less, slow); // Negative keys can't take the fast OOB path. - __ bind(&check_prototypes); - __ mov(scratch2, FieldOperand(receiver, HeapObject::kMapOffset)); - __ bind(&check_next_prototype); - __ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset)); - // scratch2: current prototype - __ cmp(scratch2, masm->isolate()->factory()->null_value()); - __ j(equal, &absent); - __ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset)); - __ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset)); - // scratch: elements of current prototype - // scratch2: map of current prototype - __ CmpInstanceType(scratch2, JS_OBJECT_TYPE); - __ j(below, slow); - __ test_b(FieldOperand(scratch2, Map::kBitFieldOffset), - Immediate((1 << Map::kIsAccessCheckNeeded) | - (1 << Map::kHasIndexedInterceptor))); - __ j(not_zero, slow); - __ cmp(scratch, masm->isolate()->factory()->empty_fixed_array()); - __ j(not_equal, slow); - __ jmp(&check_next_prototype); - - __ bind(&absent); - __ mov(result, masm->isolate()->factory()->undefined_value()); - __ jmp(&done); - - __ bind(&in_bounds); - // Fast case: Do the load. - STATIC_ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); - __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize)); - __ cmp(scratch, Immediate(masm->isolate()->factory()->the_hole_value())); - // In case the loaded value is the_hole we have to check the prototype chain. - __ j(equal, &check_prototypes); - __ Move(result, scratch); - __ bind(&done); -} - - -// Checks whether a key is an array index string or a unique name. -// Falls through if the key is a unique name. -static void GenerateKeyNameCheck(MacroAssembler* masm, Register key, - Register map, Register hash, - Label* index_string, Label* not_unique) { - // Register use: - // key - holds the key and is unchanged. Assumed to be non-smi. - // Scratch registers: - // map - used to hold the map of the key. - // hash - used to hold the hash of the key. - Label unique; - __ CmpObjectType(key, LAST_UNIQUE_NAME_TYPE, map); - __ j(above, not_unique); - STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); - __ j(equal, &unique); - - // Is the string an array index, with cached numeric value? - __ mov(hash, FieldOperand(key, Name::kHashFieldOffset)); - __ test(hash, Immediate(Name::kContainsCachedArrayIndexMask)); - __ j(zero, index_string); - - // Is the string internalized? We already know it's a string so a single - // bit test is enough. - STATIC_ASSERT(kNotInternalizedTag != 0); - __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), - Immediate(kIsNotInternalizedMask)); - __ j(not_zero, not_unique); - - __ bind(&unique); -} - -void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { - // The return address is on the stack. - Label slow, check_name, index_smi, index_name, property_array_property; - Label probe_dictionary, check_number_dictionary; - - Register receiver = LoadDescriptor::ReceiverRegister(); - Register key = LoadDescriptor::NameRegister(); - DCHECK(receiver.is(edx)); - DCHECK(key.is(ecx)); - - // Check that the key is a smi. - __ JumpIfNotSmi(key, &check_name); - __ bind(&index_smi); - // Now the key is known to be a smi. This place is also jumped to from - // where a numeric string is converted to a smi. - - GenerateKeyedLoadReceiverCheck(masm, receiver, eax, - Map::kHasIndexedInterceptor, &slow); - - // Check the receiver's map to see if it has fast elements. - __ CheckFastElements(eax, &check_number_dictionary); - - GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow); - Isolate* isolate = masm->isolate(); - Counters* counters = isolate->counters(); - __ IncrementCounter(counters->ic_keyed_load_generic_smi(), 1); - __ ret(0); - - __ bind(&check_number_dictionary); - __ mov(ebx, key); - __ SmiUntag(ebx); - __ mov(eax, FieldOperand(receiver, JSObject::kElementsOffset)); - - // Check whether the elements is a number dictionary. - // ebx: untagged index - // eax: elements - __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow, - DONT_DO_SMI_CHECK); - Label slow_pop_receiver; - // Push receiver on the stack to free up a register for the dictionary - // probing. - __ push(receiver); - __ LoadFromNumberDictionary(&slow_pop_receiver, eax, key, ebx, edx, edi, eax); - // Pop receiver before returning. - __ pop(receiver); - __ ret(0); - - __ bind(&slow_pop_receiver); - // Pop the receiver from the stack and jump to runtime. - __ pop(receiver); - - __ bind(&slow); - // Slow case: jump to runtime. - __ IncrementCounter(counters->ic_keyed_load_generic_slow(), 1); - GenerateRuntimeGetProperty(masm); - - __ bind(&check_name); - GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow); - - GenerateKeyedLoadReceiverCheck(masm, receiver, eax, Map::kHasNamedInterceptor, - &slow); - - // If the receiver is a fast-case object, check the stub cache. Otherwise - // probe the dictionary. - __ mov(ebx, FieldOperand(receiver, JSObject::kPropertiesOffset)); - __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), - Immediate(isolate->factory()->hash_table_map())); - __ j(equal, &probe_dictionary); - - // The handlers in the stub cache expect a vector and slot. Since we won't - // change the IC from any downstream misses, a dummy vector can be used. - Handle dummy_vector = - TypeFeedbackVector::DummyVector(isolate); - int slot = dummy_vector->GetIndex( - FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot)); - __ push(Immediate(Smi::FromInt(slot))); - __ push(Immediate(dummy_vector)); - - masm->isolate()->load_stub_cache()->GenerateProbe(masm, receiver, key, ebx, - edi); - - __ pop(LoadWithVectorDescriptor::VectorRegister()); - __ pop(LoadDescriptor::SlotRegister()); - - // Cache miss. - GenerateMiss(masm); - - // Do a quick inline probe of the receiver's dictionary, if it - // exists. - __ bind(&probe_dictionary); - - __ mov(eax, FieldOperand(receiver, JSObject::kMapOffset)); - __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); - GenerateGlobalInstanceTypeCheck(masm, eax, &slow); - - GenerateDictionaryLoad(masm, &slow, ebx, key, eax, edi, eax); - __ IncrementCounter(counters->ic_keyed_load_generic_symbol(), 1); - __ ret(0); - - __ bind(&index_name); - __ IndexFromHash(ebx, key); - // Now jump to the place where smi keys are handled. - __ jmp(&index_smi); -} - - static void KeyedStoreGenerateMegamorphicHelper( MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { -- cgit v1.2.3