| 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 4230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4241 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, | 4241 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, |
| 4242 Register key, Register vector, | 4242 Register key, Register vector, |
| 4243 Register slot, Register feedback, | 4243 Register slot, Register feedback, |
| 4244 bool is_polymorphic, Label* miss) { | 4244 bool is_polymorphic, Label* miss) { |
| 4245 // feedback initially contains the feedback array | 4245 // feedback initially contains the feedback array |
| 4246 Label next, next_loop, prepare_next; | 4246 Label next, next_loop, prepare_next; |
| 4247 Label load_smi_map, compare_map; | 4247 Label load_smi_map, compare_map; |
| 4248 Label start_polymorphic; | 4248 Label start_polymorphic; |
| 4249 Label pop_and_miss; | 4249 Label pop_and_miss; |
| 4250 ExternalReference virtual_register = | 4250 ExternalReference virtual_register = |
| 4251 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4251 ExternalReference::virtual_handler_register(masm->isolate()); |
| 4252 | 4252 |
| 4253 __ push(receiver); | 4253 __ push(receiver); |
| 4254 __ push(vector); | 4254 __ push(vector); |
| 4255 | 4255 |
| 4256 Register receiver_map = receiver; | 4256 Register receiver_map = receiver; |
| 4257 Register cached_map = vector; | 4257 Register cached_map = vector; |
| 4258 | 4258 |
| 4259 // Receiver might not be a heap object. | 4259 // Receiver might not be a heap object. |
| 4260 __ JumpIfSmi(receiver, &load_smi_map); | 4260 __ JumpIfSmi(receiver, &load_smi_map); |
| 4261 __ mov(receiver_map, FieldOperand(receiver, 0)); | 4261 __ mov(receiver_map, FieldOperand(receiver, 0)); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4325 } | 4325 } |
| 4326 | 4326 |
| 4327 | 4327 |
| 4328 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, | 4328 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, |
| 4329 Register key, Register vector, | 4329 Register key, Register vector, |
| 4330 Register slot, Register weak_cell, | 4330 Register slot, Register weak_cell, |
| 4331 Label* miss) { | 4331 Label* miss) { |
| 4332 // The store ic value is on the stack. | 4332 // The store ic value is on the stack. |
| 4333 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); | 4333 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); |
| 4334 ExternalReference virtual_register = | 4334 ExternalReference virtual_register = |
| 4335 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4335 ExternalReference::virtual_handler_register(masm->isolate()); |
| 4336 | 4336 |
| 4337 // feedback initially contains the feedback array | 4337 // feedback initially contains the feedback array |
| 4338 Label compare_smi_map; | 4338 Label compare_smi_map; |
| 4339 | 4339 |
| 4340 // Move the weak map into the weak_cell register. | 4340 // Move the weak map into the weak_cell register. |
| 4341 Register ic_map = weak_cell; | 4341 Register ic_map = weak_cell; |
| 4342 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); | 4342 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); |
| 4343 | 4343 |
| 4344 // Receiver might not be a heap object. | 4344 // Receiver might not be a heap object. |
| 4345 __ JumpIfSmi(receiver, &compare_smi_map); | 4345 __ JumpIfSmi(receiver, &compare_smi_map); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4433 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, | 4433 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, |
| 4434 Register receiver, Register key, | 4434 Register receiver, Register key, |
| 4435 Register vector, Register slot, | 4435 Register vector, Register slot, |
| 4436 Register feedback, Label* miss) { | 4436 Register feedback, Label* miss) { |
| 4437 // feedback initially contains the feedback array | 4437 // feedback initially contains the feedback array |
| 4438 Label next, next_loop, prepare_next; | 4438 Label next, next_loop, prepare_next; |
| 4439 Label load_smi_map, compare_map; | 4439 Label load_smi_map, compare_map; |
| 4440 Label transition_call; | 4440 Label transition_call; |
| 4441 Label pop_and_miss; | 4441 Label pop_and_miss; |
| 4442 ExternalReference virtual_register = | 4442 ExternalReference virtual_register = |
| 4443 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4443 ExternalReference::virtual_handler_register(masm->isolate()); |
| 4444 ExternalReference virtual_slot = |
| 4445 ExternalReference::virtual_slot_register(masm->isolate()); |
| 4444 | 4446 |
| 4445 __ push(receiver); | 4447 __ push(receiver); |
| 4446 __ push(vector); | 4448 __ push(vector); |
| 4447 | 4449 |
| 4448 Register receiver_map = receiver; | 4450 Register receiver_map = receiver; |
| 4449 Register cached_map = vector; | 4451 Register cached_map = vector; |
| 4452 Register value = StoreDescriptor::ValueRegister(); |
| 4450 | 4453 |
| 4451 // Receiver might not be a heap object. | 4454 // Receiver might not be a heap object. |
| 4452 __ JumpIfSmi(receiver, &load_smi_map); | 4455 __ JumpIfSmi(receiver, &load_smi_map); |
| 4453 __ mov(receiver_map, FieldOperand(receiver, 0)); | 4456 __ mov(receiver_map, FieldOperand(receiver, 0)); |
| 4454 __ bind(&compare_map); | 4457 __ bind(&compare_map); |
| 4455 | 4458 |
| 4456 // Polymorphic, we have to loop from 0 to N - 1 | 4459 // Polymorphic, we have to loop from 0 to N - 1 |
| 4457 __ push(key); | 4460 __ push(key); |
| 4458 // On the stack we have: | 4461 // Current stack layout: |
| 4459 // key (esp) | 4462 // - esp[0] -- key |
| 4460 // vector | 4463 // - esp[4] -- vector |
| 4461 // receiver | 4464 // - esp[8] -- receiver |
| 4462 // value | 4465 // - esp[12] -- value |
| 4466 // - esp[16] -- return address |
| 4467 // |
| 4468 // Required stack layout for handler call: |
| 4469 // - esp[0] -- return address |
| 4470 // - receiver, key, value, vector, slot in registers. |
| 4471 // - handler in virtual register. |
| 4463 Register counter = key; | 4472 Register counter = key; |
| 4464 __ mov(counter, Immediate(Smi::FromInt(0))); | 4473 __ mov(counter, Immediate(Smi::FromInt(0))); |
| 4465 __ bind(&next_loop); | 4474 __ bind(&next_loop); |
| 4466 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4475 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
| 4467 FixedArray::kHeaderSize)); | 4476 FixedArray::kHeaderSize)); |
| 4468 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4477 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4469 __ j(not_equal, &prepare_next); | 4478 __ j(not_equal, &prepare_next); |
| 4470 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4479 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
| 4471 FixedArray::kHeaderSize + kPointerSize)); | 4480 FixedArray::kHeaderSize + kPointerSize)); |
| 4472 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 4481 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
| 4473 __ j(not_equal, &transition_call); | 4482 __ j(not_equal, &transition_call); |
| 4474 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 4483 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
| 4475 FixedArray::kHeaderSize + 2 * kPointerSize)); | 4484 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4476 __ pop(key); | 4485 __ pop(key); |
| 4477 __ pop(vector); | 4486 __ pop(vector); |
| 4478 __ pop(receiver); | 4487 __ pop(receiver); |
| 4479 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 4488 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4480 __ mov(Operand::StaticVariable(virtual_register), feedback); | 4489 __ mov(Operand::StaticVariable(virtual_register), feedback); |
| 4481 __ pop(feedback); // Pop "value". | 4490 __ pop(value); |
| 4482 __ jmp(Operand::StaticVariable(virtual_register)); | 4491 __ jmp(Operand::StaticVariable(virtual_register)); |
| 4483 | 4492 |
| 4484 __ bind(&transition_call); | 4493 __ bind(&transition_call); |
| 4485 // Oh holy hell this will be tough. | 4494 // Current stack layout: |
| 4486 // The map goes in vector register. | 4495 // - esp[0] -- key |
| 4487 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4496 // - esp[4] -- vector |
| 4488 // The weak cell may have been cleared. | 4497 // - esp[8] -- receiver |
| 4489 __ JumpIfSmi(receiver, &pop_and_miss); | 4498 // - esp[12] -- value |
| 4490 // slot goes on the stack, and holds return address. | 4499 // - esp[16] -- return address |
| 4491 __ xchg(slot, Operand(esp, 4 * kPointerSize)); | 4500 // |
| 4492 // Get the handler in value. | 4501 // Required stack layout for handler call: |
| 4502 // - esp[0] -- return address |
| 4503 // - receiver, key, value, map, vector in registers. |
| 4504 // - handler and slot in virtual registers. |
| 4505 __ mov(Operand::StaticVariable(virtual_slot), slot); |
| 4493 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 4506 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
| 4494 FixedArray::kHeaderSize + 2 * kPointerSize)); | 4507 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4495 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 4508 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4509 __ mov(Operand::StaticVariable(virtual_register), feedback); |
| 4510 |
| 4511 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4512 // The weak cell may have been cleared. |
| 4513 __ JumpIfSmi(cached_map, &pop_and_miss); |
| 4514 DCHECK(!cached_map.is(VectorStoreTransitionDescriptor::MapRegister())); |
| 4515 __ mov(VectorStoreTransitionDescriptor::MapRegister(), cached_map); |
| 4516 |
| 4496 // Pop key into place. | 4517 // Pop key into place. |
| 4497 __ pop(key); | 4518 __ pop(key); |
| 4498 // Put the return address on top of stack, vector goes in slot. | 4519 __ pop(vector); |
| 4499 __ xchg(slot, Operand(esp, 0)); | 4520 __ pop(receiver); |
| 4500 // put the map on the stack, receiver holds receiver. | 4521 __ pop(value); |
| 4501 __ xchg(receiver, Operand(esp, 1 * kPointerSize)); | 4522 __ jmp(Operand::StaticVariable(virtual_register)); |
| 4502 // put the vector on the stack, slot holds value. | |
| 4503 __ xchg(slot, Operand(esp, 2 * kPointerSize)); | |
| 4504 // feedback (value) = value, slot = handler. | |
| 4505 __ xchg(feedback, slot); | |
| 4506 __ jmp(slot); | |
| 4507 | 4523 |
| 4508 __ bind(&prepare_next); | 4524 __ bind(&prepare_next); |
| 4509 __ add(counter, Immediate(Smi::FromInt(3))); | 4525 __ add(counter, Immediate(Smi::FromInt(3))); |
| 4510 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 4526 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
| 4511 __ j(less, &next_loop); | 4527 __ j(less, &next_loop); |
| 4512 | 4528 |
| 4513 // We exhausted our array of map handler pairs. | 4529 // We exhausted our array of map handler pairs. |
| 4514 __ bind(&pop_and_miss); | 4530 __ bind(&pop_and_miss); |
| 4515 __ pop(key); | 4531 __ pop(key); |
| 4516 __ pop(vector); | 4532 __ pop(vector); |
| (...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5501 Operand(ebp, 7 * kPointerSize), NULL); | 5517 Operand(ebp, 7 * kPointerSize), NULL); |
| 5502 } | 5518 } |
| 5503 | 5519 |
| 5504 | 5520 |
| 5505 #undef __ | 5521 #undef __ |
| 5506 | 5522 |
| 5507 } // namespace internal | 5523 } // namespace internal |
| 5508 } // namespace v8 | 5524 } // namespace v8 |
| 5509 | 5525 |
| 5510 #endif // V8_TARGET_ARCH_X87 | 5526 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |