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 |