| 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 |