| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 | 
| 6 | 6 | 
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" | 
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" | 
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" | 
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" | 
| (...skipping 4229 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4240 | 4240 | 
| 4241 // value is on the stack already. | 4241 // value is on the stack already. | 
| 4242 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, | 4242 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, | 
| 4243                                        Register key, Register vector, | 4243                                        Register key, Register vector, | 
| 4244                                        Register slot, Register feedback, | 4244                                        Register slot, Register feedback, | 
| 4245                                        Label* miss) { | 4245                                        Label* miss) { | 
| 4246   // feedback initially contains the feedback array | 4246   // feedback initially contains the feedback array | 
| 4247   Label next, next_loop, prepare_next; | 4247   Label next, next_loop, prepare_next; | 
| 4248   Label load_smi_map, compare_map; | 4248   Label load_smi_map, compare_map; | 
| 4249   Label start_polymorphic; | 4249   Label start_polymorphic; | 
|  | 4250   ExternalReference virtual_register = | 
|  | 4251       ExternalReference::vector_store_virtual_register(masm->isolate()); | 
| 4250 | 4252 | 
| 4251   __ push(receiver); | 4253   __ push(receiver); | 
| 4252   __ push(vector); | 4254   __ push(vector); | 
| 4253 | 4255 | 
| 4254   Register receiver_map = receiver; | 4256   Register receiver_map = receiver; | 
| 4255   Register cached_map = vector; | 4257   Register cached_map = vector; | 
| 4256 | 4258 | 
| 4257   // Receiver might not be a heap object. | 4259   // Receiver might not be a heap object. | 
| 4258   __ JumpIfSmi(receiver, &load_smi_map); | 4260   __ JumpIfSmi(receiver, &load_smi_map); | 
| 4259   __ mov(receiver_map, FieldOperand(receiver, 0)); | 4261   __ mov(receiver_map, FieldOperand(receiver, 0)); | 
| 4260   __ bind(&compare_map); | 4262   __ bind(&compare_map); | 
| 4261   __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); | 4263   __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); | 
| 4262 | 4264 | 
| 4263   // A named keyed store might have a 2 element array, all other cases can count | 4265   // A named keyed store might have a 2 element array, all other cases can count | 
| 4264   // on an array with at least 2 {map, handler} pairs, so they can go right | 4266   // on an array with at least 2 {map, handler} pairs, so they can go right | 
| 4265   // into polymorphic array handling. | 4267   // into polymorphic array handling. | 
| 4266   __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4268   __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 
| 4267   __ j(not_equal, &start_polymorphic); | 4269   __ j(not_equal, &start_polymorphic); | 
| 4268 | 4270 | 
| 4269   // found, now call handler. | 4271   // found, now call handler. | 
| 4270   Register handler = feedback; | 4272   Register handler = feedback; | 
| 4271   DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister())); | 4273   DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister())); | 
| 4272   __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); | 4274   __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); | 
| 4273   __ pop(vector); | 4275   __ pop(vector); | 
| 4274   __ pop(receiver); | 4276   __ pop(receiver); | 
| 4275   __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4277   __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 
| 4276   __ xchg(handler, Operand(esp, 0)); | 4278   __ mov(Operand::StaticVariable(virtual_register), handler); | 
| 4277   __ ret(0); | 4279   __ pop(handler);  // Pop "value". | 
|  | 4280   __ jmp(Operand::StaticVariable(virtual_register)); | 
| 4278 | 4281 | 
| 4279   // Polymorphic, we have to loop from 2 to N | 4282   // Polymorphic, we have to loop from 2 to N | 
| 4280 | 4283 | 
| 4281   // TODO(mvstanton): I think there is a bug here, we are assuming the | 4284   // TODO(mvstanton): I think there is a bug here, we are assuming the | 
| 4282   // array has more than one map/handler pair, but we call this function in the | 4285   // array has more than one map/handler pair, but we call this function in the | 
| 4283   // keyed store with a string key case, where it might be just an array of two | 4286   // keyed store with a string key case, where it might be just an array of two | 
| 4284   // elements. | 4287   // elements. | 
| 4285 | 4288 | 
| 4286   __ bind(&start_polymorphic); | 4289   __ bind(&start_polymorphic); | 
| 4287   __ push(key); | 4290   __ push(key); | 
| 4288   Register counter = key; | 4291   Register counter = key; | 
| 4289   __ mov(counter, Immediate(Smi::FromInt(2))); | 4292   __ mov(counter, Immediate(Smi::FromInt(2))); | 
| 4290   __ bind(&next_loop); | 4293   __ bind(&next_loop); | 
| 4291   __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4294   __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 
| 4292                                   FixedArray::kHeaderSize)); | 4295                                   FixedArray::kHeaderSize)); | 
| 4293   __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4296   __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 
| 4294   __ j(not_equal, &prepare_next); | 4297   __ j(not_equal, &prepare_next); | 
| 4295   __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, | 4298   __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, | 
| 4296                                FixedArray::kHeaderSize + kPointerSize)); | 4299                                FixedArray::kHeaderSize + kPointerSize)); | 
|  | 4300   __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 
| 4297   __ pop(key); | 4301   __ pop(key); | 
| 4298   __ pop(vector); | 4302   __ pop(vector); | 
| 4299   __ pop(receiver); | 4303   __ pop(receiver); | 
| 4300   __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4304   __ mov(Operand::StaticVariable(virtual_register), handler); | 
| 4301   __ xchg(handler, Operand(esp, 0)); | 4305   __ pop(handler);  // Pop "value". | 
| 4302   __ ret(0); | 4306   __ jmp(Operand::StaticVariable(virtual_register)); | 
| 4303 | 4307 | 
| 4304   __ bind(&prepare_next); | 4308   __ bind(&prepare_next); | 
| 4305   __ add(counter, Immediate(Smi::FromInt(2))); | 4309   __ add(counter, Immediate(Smi::FromInt(2))); | 
| 4306   __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 4310   __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 
| 4307   __ j(less, &next_loop); | 4311   __ j(less, &next_loop); | 
| 4308 | 4312 | 
| 4309   // We exhausted our array of map handler pairs. | 4313   // We exhausted our array of map handler pairs. | 
| 4310   __ pop(key); | 4314   __ pop(key); | 
| 4311   __ pop(vector); | 4315   __ pop(vector); | 
| 4312   __ pop(receiver); | 4316   __ pop(receiver); | 
| 4313   __ jmp(miss); | 4317   __ jmp(miss); | 
| 4314 | 4318 | 
| 4315   __ bind(&load_smi_map); | 4319   __ bind(&load_smi_map); | 
| 4316   __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | 4320   __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | 
| 4317   __ jmp(&compare_map); | 4321   __ jmp(&compare_map); | 
| 4318 } | 4322 } | 
| 4319 | 4323 | 
| 4320 | 4324 | 
| 4321 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, | 4325 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, | 
| 4322                                        Register key, Register vector, | 4326                                        Register key, Register vector, | 
| 4323                                        Register slot, Register weak_cell, | 4327                                        Register slot, Register weak_cell, | 
| 4324                                        Label* miss) { | 4328                                        Label* miss) { | 
| 4325   // The store ic value is on the stack. | 4329   // The store ic value is on the stack. | 
| 4326   DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); | 4330   DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); | 
|  | 4331   ExternalReference virtual_register = | 
|  | 4332       ExternalReference::vector_store_virtual_register(masm->isolate()); | 
| 4327 | 4333 | 
| 4328   // feedback initially contains the feedback array | 4334   // feedback initially contains the feedback array | 
| 4329   Label compare_smi_map; | 4335   Label compare_smi_map; | 
| 4330 | 4336 | 
| 4331   // Move the weak map into the weak_cell register. | 4337   // Move the weak map into the weak_cell register. | 
| 4332   Register ic_map = weak_cell; | 4338   Register ic_map = weak_cell; | 
| 4333   __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); | 4339   __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); | 
| 4334 | 4340 | 
| 4335   // Receiver might not be a heap object. | 4341   // Receiver might not be a heap object. | 
| 4336   __ JumpIfSmi(receiver, &compare_smi_map); | 4342   __ JumpIfSmi(receiver, &compare_smi_map); | 
| 4337   __ cmp(ic_map, FieldOperand(receiver, 0)); | 4343   __ cmp(ic_map, FieldOperand(receiver, 0)); | 
| 4338   __ j(not_equal, miss); | 4344   __ j(not_equal, miss); | 
| 4339   __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, | 4345   __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, | 
| 4340                                  FixedArray::kHeaderSize + kPointerSize)); | 4346                                  FixedArray::kHeaderSize + kPointerSize)); | 
| 4341   __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); | 4347   __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); | 
| 4342   // Put the store ic value back in it's register. | 4348   // Put the store ic value back in it's register. | 
| 4343   __ xchg(weak_cell, Operand(esp, 0)); | 4349   __ mov(Operand::StaticVariable(virtual_register), weak_cell); | 
| 4344   // "return" to the handler. | 4350   __ pop(weak_cell);  // Pop "value". | 
| 4345   __ ret(0); | 4351   // jump to the handler. | 
|  | 4352   __ jmp(Operand::StaticVariable(virtual_register)); | 
| 4346 | 4353 | 
| 4347   // In microbenchmarks, it made sense to unroll this code so that the call to | 4354   // In microbenchmarks, it made sense to unroll this code so that the call to | 
| 4348   // the handler is duplicated for a HeapObject receiver and a Smi receiver. | 4355   // the handler is duplicated for a HeapObject receiver and a Smi receiver. | 
| 4349   __ bind(&compare_smi_map); | 4356   __ bind(&compare_smi_map); | 
| 4350   __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); | 4357   __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); | 
| 4351   __ j(not_equal, miss); | 4358   __ j(not_equal, miss); | 
| 4352   __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, | 4359   __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, | 
| 4353                                  FixedArray::kHeaderSize + kPointerSize)); | 4360                                  FixedArray::kHeaderSize + kPointerSize)); | 
| 4354   __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); | 4361   __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); | 
| 4355   // Put the store ic value back in it's register. | 4362   __ mov(Operand::StaticVariable(virtual_register), weak_cell); | 
| 4356   __ xchg(weak_cell, Operand(esp, 0)); | 4363   __ pop(weak_cell);  // Pop "value". | 
| 4357   // "return" to the handler. | 4364   // jump to the handler. | 
| 4358   __ ret(0); | 4365   __ jmp(Operand::StaticVariable(virtual_register)); | 
| 4359 } | 4366 } | 
| 4360 | 4367 | 
| 4361 | 4368 | 
| 4362 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4369 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 
| 4363   Register receiver = VectorStoreICDescriptor::ReceiverRegister();  // edx | 4370   Register receiver = VectorStoreICDescriptor::ReceiverRegister();  // edx | 
| 4364   Register key = VectorStoreICDescriptor::NameRegister();           // ecx | 4371   Register key = VectorStoreICDescriptor::NameRegister();           // ecx | 
| 4365   Register value = VectorStoreICDescriptor::ValueRegister();        // eax | 4372   Register value = VectorStoreICDescriptor::ValueRegister();        // eax | 
| 4366   Register vector = VectorStoreICDescriptor::VectorRegister();      // ebx | 4373   Register vector = VectorStoreICDescriptor::VectorRegister();      // ebx | 
| 4367   Register slot = VectorStoreICDescriptor::SlotRegister();          // edi | 4374   Register slot = VectorStoreICDescriptor::SlotRegister();          // edi | 
| 4368   Label miss; | 4375   Label miss; | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4421 | 4428 | 
| 4422 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, | 4429 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, | 
| 4423                                             Register receiver, Register key, | 4430                                             Register receiver, Register key, | 
| 4424                                             Register vector, Register slot, | 4431                                             Register vector, Register slot, | 
| 4425                                             Register feedback, Label* miss) { | 4432                                             Register feedback, Label* miss) { | 
| 4426   // feedback initially contains the feedback array | 4433   // feedback initially contains the feedback array | 
| 4427   Label next, next_loop, prepare_next; | 4434   Label next, next_loop, prepare_next; | 
| 4428   Label load_smi_map, compare_map; | 4435   Label load_smi_map, compare_map; | 
| 4429   Label transition_call; | 4436   Label transition_call; | 
| 4430   Label pop_and_miss; | 4437   Label pop_and_miss; | 
|  | 4438   ExternalReference virtual_register = | 
|  | 4439       ExternalReference::vector_store_virtual_register(masm->isolate()); | 
| 4431 | 4440 | 
| 4432   __ push(receiver); | 4441   __ push(receiver); | 
| 4433   __ push(vector); | 4442   __ push(vector); | 
| 4434 | 4443 | 
| 4435   Register receiver_map = receiver; | 4444   Register receiver_map = receiver; | 
| 4436   Register cached_map = vector; | 4445   Register cached_map = vector; | 
| 4437 | 4446 | 
| 4438   // Receiver might not be a heap object. | 4447   // Receiver might not be a heap object. | 
| 4439   __ JumpIfSmi(receiver, &load_smi_map); | 4448   __ JumpIfSmi(receiver, &load_smi_map); | 
| 4440   __ mov(receiver_map, FieldOperand(receiver, 0)); | 4449   __ mov(receiver_map, FieldOperand(receiver, 0)); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 4457   __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4466   __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 
| 4458                                   FixedArray::kHeaderSize + kPointerSize)); | 4467                                   FixedArray::kHeaderSize + kPointerSize)); | 
| 4459   __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 4468   __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 
| 4460   __ j(not_equal, &transition_call); | 4469   __ j(not_equal, &transition_call); | 
| 4461   __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 4470   __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 
| 4462                                 FixedArray::kHeaderSize + 2 * kPointerSize)); | 4471                                 FixedArray::kHeaderSize + 2 * kPointerSize)); | 
| 4463   __ pop(key); | 4472   __ pop(key); | 
| 4464   __ pop(vector); | 4473   __ pop(vector); | 
| 4465   __ pop(receiver); | 4474   __ pop(receiver); | 
| 4466   __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 4475   __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 
| 4467   __ xchg(feedback, Operand(esp, 0)); | 4476   __ mov(Operand::StaticVariable(virtual_register), feedback); | 
| 4468   __ ret(0); | 4477   __ pop(feedback);  // Pop "value". | 
|  | 4478   __ jmp(Operand::StaticVariable(virtual_register)); | 
| 4469 | 4479 | 
| 4470   __ bind(&transition_call); | 4480   __ bind(&transition_call); | 
| 4471   // Oh holy hell this will be tough. | 4481   // Oh holy hell this will be tough. | 
| 4472   // The map goes in vector register. | 4482   // The map goes in vector register. | 
| 4473   __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4483   __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); | 
| 4474   // The weak cell may have been cleared. | 4484   // The weak cell may have been cleared. | 
| 4475   __ JumpIfSmi(receiver, &pop_and_miss); | 4485   __ JumpIfSmi(receiver, &pop_and_miss); | 
| 4476   // slot goes on the stack, and holds return address. | 4486   // slot goes on the stack, and holds return address. | 
| 4477   __ xchg(slot, Operand(esp, 4 * kPointerSize)); | 4487   __ xchg(slot, Operand(esp, 4 * kPointerSize)); | 
| 4478   // Get the handler in value. | 4488   // Get the handler in value. | 
| (...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5486                            Operand(ebp, 7 * kPointerSize), NULL); | 5496                            Operand(ebp, 7 * kPointerSize), NULL); | 
| 5487 } | 5497 } | 
| 5488 | 5498 | 
| 5489 | 5499 | 
| 5490 #undef __ | 5500 #undef __ | 
| 5491 | 5501 | 
| 5492 }  // namespace internal | 5502 }  // namespace internal | 
| 5493 }  // namespace v8 | 5503 }  // namespace v8 | 
| 5494 | 5504 | 
| 5495 #endif  // V8_TARGET_ARCH_X87 | 5505 #endif  // V8_TARGET_ARCH_X87 | 
| OLD | NEW | 
|---|