OLD | NEW |
1 // Copyright 2014 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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/ic/call-optimization.h" | 9 #include "src/ic/call-optimization.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 #define __ ACCESS_MASM(masm) | 15 #define __ ACCESS_MASM(masm) |
16 | 16 |
17 | 17 |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 319 |
320 static void CompileCallLoadPropertyWithInterceptor( | 320 static void CompileCallLoadPropertyWithInterceptor( |
321 MacroAssembler* masm, Register receiver, Register holder, Register name, | 321 MacroAssembler* masm, Register receiver, Register holder, Register name, |
322 Handle<JSObject> holder_obj, IC::UtilityId id) { | 322 Handle<JSObject> holder_obj, IC::UtilityId id) { |
323 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 323 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
324 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), | 324 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), |
325 NamedLoadHandlerCompiler::kInterceptorArgsLength); | 325 NamedLoadHandlerCompiler::kInterceptorArgsLength); |
326 } | 326 } |
327 | 327 |
328 | 328 |
329 static void StoreIC_PushArgs(MacroAssembler* masm) { | |
330 Register receiver = StoreIC::ReceiverRegister(); | |
331 Register name = StoreIC::NameRegister(); | |
332 Register value = StoreIC::ValueRegister(); | |
333 | |
334 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); | |
335 | |
336 __ pop(ebx); | |
337 __ push(receiver); | |
338 __ push(name); | |
339 __ push(value); | |
340 __ push(ebx); | |
341 } | |
342 | |
343 | |
344 void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { | |
345 // Return address is on the stack. | |
346 StoreIC_PushArgs(masm); | |
347 | |
348 // Do tail-call to runtime routine. | |
349 ExternalReference ref(IC_Utility(IC::kStoreIC_Slow), masm->isolate()); | |
350 __ TailCallExternalReference(ref, 3, 1); | |
351 } | |
352 | |
353 | |
354 void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) { | |
355 // Return address is on the stack. | |
356 StoreIC_PushArgs(masm); | |
357 | |
358 // Do tail-call to runtime routine. | |
359 ExternalReference ref(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate()); | |
360 __ TailCallExternalReference(ref, 3, 1); | |
361 } | |
362 | |
363 | |
364 #undef __ | 329 #undef __ |
365 #define __ ACCESS_MASM(masm()) | 330 #define __ ACCESS_MASM(masm()) |
366 | 331 |
367 | 332 |
368 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, | 333 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
369 Handle<Name> name) { | 334 Handle<Name> name) { |
370 if (!label->is_unused()) { | 335 if (!label->is_unused()) { |
371 __ bind(label); | 336 __ bind(label); |
372 __ mov(this->name(), Immediate(name)); | 337 __ mov(this->name(), Immediate(name)); |
373 } | 338 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 __ j(equal, &do_store, Label::kNear); | 373 __ j(equal, &do_store, Label::kNear); |
409 } | 374 } |
410 __ bind(&do_store); | 375 __ bind(&do_store); |
411 } | 376 } |
412 } else if (representation.IsDouble()) { | 377 } else if (representation.IsDouble()) { |
413 Label do_store, heap_number; | 378 Label do_store, heap_number; |
414 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE); | 379 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE); |
415 | 380 |
416 __ JumpIfNotSmi(value_reg, &heap_number); | 381 __ JumpIfNotSmi(value_reg, &heap_number); |
417 __ SmiUntag(value_reg); | 382 __ SmiUntag(value_reg); |
418 __ Cvtsi2sd(xmm0, value_reg); | 383 __ push(value_reg); |
| 384 __ fild_s(Operand(esp, 0)); |
| 385 __ pop(value_reg); |
419 __ SmiTag(value_reg); | 386 __ SmiTag(value_reg); |
420 __ jmp(&do_store); | 387 __ jmp(&do_store); |
421 | 388 |
422 __ bind(&heap_number); | 389 __ bind(&heap_number); |
423 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, | 390 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, |
424 DONT_DO_SMI_CHECK); | 391 DONT_DO_SMI_CHECK); |
425 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 392 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); |
426 | 393 |
427 __ bind(&do_store); | 394 __ bind(&do_store); |
428 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); | 395 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); |
429 } | 396 } |
430 | 397 |
431 // Stub never generated for objects that require access checks. | 398 // Stub never generated for objects that require access checks. |
432 DCHECK(!transition->is_access_check_needed()); | 399 DCHECK(!transition->is_access_check_needed()); |
433 | 400 |
434 // Perform map transition for the receiver if necessary. | 401 // Perform map transition for the receiver if necessary. |
435 if (details.type() == FIELD && | 402 if (details.type() == FIELD && |
436 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { | 403 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { |
437 // The properties must be extended before we can store the value. | 404 // The properties must be extended before we can store the value. |
438 // We jump to a runtime call that extends the properties array. | 405 // We jump to a runtime call that extends the properties array. |
439 __ pop(scratch1); // Return address. | 406 __ pop(scratch1); // Return address. |
440 __ push(receiver_reg); | 407 __ push(receiver_reg); |
441 __ push(Immediate(transition)); | 408 __ push(Immediate(transition)); |
442 __ push(value_reg); | 409 __ push(value_reg); |
443 __ push(scratch1); | 410 __ push(scratch1); |
444 __ TailCallExternalReference( | 411 __ TailCallExternalReference( |
445 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 412 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
446 isolate()), | 413 isolate()), |
447 3, 1); | 414 3, 1); |
448 return; | 415 return; |
449 } | 416 } |
450 | 417 |
451 // Update the map of the object. | 418 // Update the map of the object. |
452 __ mov(scratch1, Immediate(transition)); | 419 __ mov(scratch1, Immediate(transition)); |
453 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); | 420 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); |
454 | 421 |
455 // Update the write barrier for the map field. | 422 // Update the write barrier for the map field. |
456 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, | 423 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, |
457 kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 424 OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
458 | 425 |
459 if (details.type() == CONSTANT) { | 426 if (details.type() == CONSTANT) { |
460 DCHECK(value_reg.is(eax)); | 427 DCHECK(value_reg.is(eax)); |
461 __ ret(0); | 428 __ ret(0); |
462 return; | 429 return; |
463 } | 430 } |
464 | 431 |
465 int index = transition->instance_descriptors()->GetFieldIndex( | 432 int index = transition->instance_descriptors()->GetFieldIndex( |
466 transition->LastAdded()); | 433 transition->LastAdded()); |
467 | 434 |
(...skipping 13 matching lines...) Expand all Loading... |
481 } else { | 448 } else { |
482 __ mov(FieldOperand(receiver_reg, offset), value_reg); | 449 __ mov(FieldOperand(receiver_reg, offset), value_reg); |
483 } | 450 } |
484 | 451 |
485 if (!representation.IsSmi()) { | 452 if (!representation.IsSmi()) { |
486 // Update the write barrier for the array address. | 453 // Update the write barrier for the array address. |
487 if (!representation.IsDouble()) { | 454 if (!representation.IsDouble()) { |
488 __ mov(storage_reg, value_reg); | 455 __ mov(storage_reg, value_reg); |
489 } | 456 } |
490 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, | 457 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, |
491 kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); | 458 EMIT_REMEMBERED_SET, smi_check); |
492 } | 459 } |
493 } else { | 460 } else { |
494 // Write to the properties array. | 461 // Write to the properties array. |
495 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 462 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
496 // Get the properties array (optimistically). | 463 // Get the properties array (optimistically). |
497 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 464 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
498 if (representation.IsDouble()) { | 465 if (representation.IsDouble()) { |
499 __ mov(FieldOperand(scratch1, offset), storage_reg); | 466 __ mov(FieldOperand(scratch1, offset), storage_reg); |
500 } else { | 467 } else { |
501 __ mov(FieldOperand(scratch1, offset), value_reg); | 468 __ mov(FieldOperand(scratch1, offset), value_reg); |
502 } | 469 } |
503 | 470 |
504 if (!representation.IsSmi()) { | 471 if (!representation.IsSmi()) { |
505 // Update the write barrier for the array address. | 472 // Update the write barrier for the array address. |
506 if (!representation.IsDouble()) { | 473 if (!representation.IsDouble()) { |
507 __ mov(storage_reg, value_reg); | 474 __ mov(storage_reg, value_reg); |
508 } | 475 } |
509 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, | 476 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, |
510 kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); | 477 EMIT_REMEMBERED_SET, smi_check); |
511 } | 478 } |
512 } | 479 } |
513 | 480 |
514 // Return the value (register eax). | 481 // Return the value (register eax). |
515 DCHECK(value_reg.is(eax)); | 482 DCHECK(value_reg.is(eax)); |
516 __ ret(0); | 483 __ ret(0); |
517 } | 484 } |
518 | 485 |
519 | 486 |
520 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, | 487 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 | 854 |
888 // Return the generated code. | 855 // Return the generated code. |
889 return GetCode(kind(), Code::NORMAL, name); | 856 return GetCode(kind(), Code::NORMAL, name); |
890 } | 857 } |
891 | 858 |
892 | 859 |
893 #undef __ | 860 #undef __ |
894 } | 861 } |
895 } // namespace v8::internal | 862 } // namespace v8::internal |
896 | 863 |
897 #endif // V8_TARGET_ARCH_IA32 | 864 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |