Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1344383002: X87: Reland VectorICs: ia32 store ics need a virtual register. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/x87/stub-cache-x87.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic/x87/stub-cache-x87.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698