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 4223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4234 | 4234 |
4235 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4235 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4236 GenerateImpl(masm, true); | 4236 GenerateImpl(masm, true); |
4237 } | 4237 } |
4238 | 4238 |
4239 | 4239 |
4240 // value is on the stack already. | 4240 // value is on the stack already. |
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 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 ExternalReference virtual_register = | 4250 ExternalReference virtual_register = |
4250 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4251 ExternalReference::vector_store_virtual_register(masm->isolate()); |
4251 | 4252 |
4252 __ push(receiver); | 4253 __ push(receiver); |
4253 __ push(vector); | 4254 __ push(vector); |
4254 | 4255 |
4255 Register receiver_map = receiver; | 4256 Register receiver_map = receiver; |
4256 Register cached_map = vector; | 4257 Register cached_map = vector; |
4257 | 4258 |
4258 // Receiver might not be a heap object. | 4259 // Receiver might not be a heap object. |
(...skipping 13 matching lines...) Expand all Loading... |
4272 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister())); | 4273 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister())); |
4273 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); | 4274 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); |
4274 __ pop(vector); | 4275 __ pop(vector); |
4275 __ pop(receiver); | 4276 __ pop(receiver); |
4276 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4277 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); |
4277 __ mov(Operand::StaticVariable(virtual_register), handler); | 4278 __ mov(Operand::StaticVariable(virtual_register), handler); |
4278 __ pop(handler); // Pop "value". | 4279 __ pop(handler); // Pop "value". |
4279 __ jmp(Operand::StaticVariable(virtual_register)); | 4280 __ jmp(Operand::StaticVariable(virtual_register)); |
4280 | 4281 |
4281 // Polymorphic, we have to loop from 2 to N | 4282 // Polymorphic, we have to loop from 2 to N |
4282 | |
4283 // TODO(mvstanton): I think there is a bug here, we are assuming the | |
4284 // array has more than one map/handler pair, but we call this function in the | |
4285 // keyed store with a string key case, where it might be just an array of two | |
4286 // elements. | |
4287 | |
4288 __ bind(&start_polymorphic); | 4283 __ bind(&start_polymorphic); |
4289 __ push(key); | 4284 __ push(key); |
4290 Register counter = key; | 4285 Register counter = key; |
4291 __ mov(counter, Immediate(Smi::FromInt(2))); | 4286 __ mov(counter, Immediate(Smi::FromInt(2))); |
| 4287 |
| 4288 if (!is_polymorphic) { |
| 4289 // If is_polymorphic is false, we may only have a two element array. |
| 4290 // Check against length now in that case. |
| 4291 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
| 4292 __ j(greater_equal, &pop_and_miss); |
| 4293 } |
| 4294 |
4292 __ bind(&next_loop); | 4295 __ bind(&next_loop); |
4293 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4296 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
4294 FixedArray::kHeaderSize)); | 4297 FixedArray::kHeaderSize)); |
4295 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4298 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
4296 __ j(not_equal, &prepare_next); | 4299 __ j(not_equal, &prepare_next); |
4297 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, | 4300 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, |
4298 FixedArray::kHeaderSize + kPointerSize)); | 4301 FixedArray::kHeaderSize + kPointerSize)); |
4299 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4302 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); |
4300 __ pop(key); | 4303 __ pop(key); |
4301 __ pop(vector); | 4304 __ pop(vector); |
4302 __ pop(receiver); | 4305 __ pop(receiver); |
4303 __ mov(Operand::StaticVariable(virtual_register), handler); | 4306 __ mov(Operand::StaticVariable(virtual_register), handler); |
4304 __ pop(handler); // Pop "value". | 4307 __ pop(handler); // Pop "value". |
4305 __ jmp(Operand::StaticVariable(virtual_register)); | 4308 __ jmp(Operand::StaticVariable(virtual_register)); |
4306 | 4309 |
4307 __ bind(&prepare_next); | 4310 __ bind(&prepare_next); |
4308 __ add(counter, Immediate(Smi::FromInt(2))); | 4311 __ add(counter, Immediate(Smi::FromInt(2))); |
4309 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 4312 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
4310 __ j(less, &next_loop); | 4313 __ j(less, &next_loop); |
4311 | 4314 |
4312 // We exhausted our array of map handler pairs. | 4315 // We exhausted our array of map handler pairs. |
| 4316 __ bind(&pop_and_miss); |
4313 __ pop(key); | 4317 __ pop(key); |
4314 __ pop(vector); | 4318 __ pop(vector); |
4315 __ pop(receiver); | 4319 __ pop(receiver); |
4316 __ jmp(miss); | 4320 __ jmp(miss); |
4317 | 4321 |
4318 __ bind(&load_smi_map); | 4322 __ bind(&load_smi_map); |
4319 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | 4323 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
4320 __ jmp(&compare_map); | 4324 __ jmp(&compare_map); |
4321 } | 4325 } |
4322 | 4326 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4383 Label try_array; | 4387 Label try_array; |
4384 Label not_array, smi_key, key_okay; | 4388 Label not_array, smi_key, key_okay; |
4385 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 4389 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
4386 __ j(not_equal, &try_array); | 4390 __ j(not_equal, &try_array); |
4387 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); | 4391 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); |
4388 | 4392 |
4389 // Is it a fixed array? | 4393 // Is it a fixed array? |
4390 __ bind(&try_array); | 4394 __ bind(&try_array); |
4391 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); | 4395 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); |
4392 __ j(not_equal, ¬_array); | 4396 __ j(not_equal, ¬_array); |
4393 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); | 4397 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true, |
| 4398 &miss); |
4394 | 4399 |
4395 __ bind(¬_array); | 4400 __ bind(¬_array); |
4396 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); | 4401 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); |
4397 __ j(not_equal, &miss); | 4402 __ j(not_equal, &miss); |
4398 | 4403 |
4399 __ pop(value); | 4404 __ pop(value); |
4400 __ push(slot); | 4405 __ push(slot); |
4401 __ push(vector); | 4406 __ push(vector); |
4402 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( | 4407 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( |
4403 Code::ComputeHandlerFlags(Code::STORE_IC)); | 4408 Code::ComputeHandlerFlags(Code::STORE_IC)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4558 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); | 4563 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); |
4559 | 4564 |
4560 __ bind(&try_poly_name); | 4565 __ bind(&try_poly_name); |
4561 // We might have a name in feedback, and a fixed array in the next slot. | 4566 // We might have a name in feedback, and a fixed array in the next slot. |
4562 __ cmp(key, scratch); | 4567 __ cmp(key, scratch); |
4563 __ j(not_equal, &miss); | 4568 __ j(not_equal, &miss); |
4564 // If the name comparison succeeded, we know we have a fixed array with | 4569 // If the name comparison succeeded, we know we have a fixed array with |
4565 // at least one map/handler pair. | 4570 // at least one map/handler pair. |
4566 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 4571 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
4567 FixedArray::kHeaderSize + kPointerSize)); | 4572 FixedArray::kHeaderSize + kPointerSize)); |
4568 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); | 4573 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false, |
| 4574 &miss); |
4569 | 4575 |
4570 __ bind(&miss); | 4576 __ bind(&miss); |
4571 __ pop(value); | 4577 __ pop(value); |
4572 KeyedStoreIC::GenerateMiss(masm); | 4578 KeyedStoreIC::GenerateMiss(masm); |
4573 } | 4579 } |
4574 | 4580 |
4575 | 4581 |
4576 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4582 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
4577 __ EmitLoadTypeFeedbackVector(ebx); | 4583 __ EmitLoadTypeFeedbackVector(ebx); |
4578 CallICStub stub(isolate(), state()); | 4584 CallICStub stub(isolate(), state()); |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5495 Operand(ebp, 7 * kPointerSize), NULL); | 5501 Operand(ebp, 7 * kPointerSize), NULL); |
5496 } | 5502 } |
5497 | 5503 |
5498 | 5504 |
5499 #undef __ | 5505 #undef __ |
5500 | 5506 |
5501 } // namespace internal | 5507 } // namespace internal |
5502 } // namespace v8 | 5508 } // namespace v8 |
5503 | 5509 |
5504 #endif // V8_TARGET_ARCH_X87 | 5510 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |