OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 miss_restore_name); | 505 miss_restore_name); |
506 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 506 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
507 GenerateDictionaryNegativeLookup( | 507 GenerateDictionaryNegativeLookup( |
508 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 508 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
509 } | 509 } |
510 } | 510 } |
511 } | 511 } |
512 | 512 |
513 Register storage_reg = name_reg; | 513 Register storage_reg = name_reg; |
514 | 514 |
515 if (details.type() == CONSTANT_FUNCTION) { | 515 if (FLAG_track_fields && representation.IsSmi()) { |
516 Handle<HeapObject> constant( | |
517 HeapObject::cast(descriptors->GetValue(descriptor))); | |
518 __ LoadHeapObject(scratch1, constant); | |
519 __ cmp(value_reg, scratch1); | |
520 __ b(ne, miss_restore_name); | |
521 } else if (FLAG_track_fields && representation.IsSmi()) { | |
522 __ JumpIfNotSmi(value_reg, miss_restore_name); | 516 __ JumpIfNotSmi(value_reg, miss_restore_name); |
523 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 517 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
524 __ JumpIfSmi(value_reg, miss_restore_name); | 518 __ JumpIfSmi(value_reg, miss_restore_name); |
525 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 519 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
526 Label do_store, heap_number; | 520 Label do_store, heap_number; |
527 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); | 521 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); |
528 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); | 522 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); |
529 | 523 |
530 __ JumpIfNotSmi(value_reg, &heap_number); | 524 __ JumpIfNotSmi(value_reg, &heap_number); |
531 __ SmiUntag(scratch1, value_reg); | 525 __ SmiUntag(scratch1, value_reg); |
532 __ vmov(s0, scratch1); | 526 __ vmov(s0, scratch1); |
533 __ vcvt_f64_s32(d0, s0); | 527 __ vcvt_f64_s32(d0, s0); |
534 __ jmp(&do_store); | 528 __ jmp(&do_store); |
535 | 529 |
536 __ bind(&heap_number); | 530 __ bind(&heap_number); |
537 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 531 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, |
538 miss_restore_name, DONT_DO_SMI_CHECK); | 532 miss_restore_name, DONT_DO_SMI_CHECK); |
539 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | 533 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
540 | 534 |
541 __ bind(&do_store); | 535 __ bind(&do_store); |
542 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); | 536 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
543 } | 537 } |
544 | 538 |
545 // Stub never generated for non-global objects that require access | 539 // Stub never generated for non-global objects that require access |
546 // checks. | 540 // checks. |
547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 541 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
548 | 542 |
549 // Perform map transition for the receiver if necessary. | 543 // Perform map transition for the receiver if necessary. |
550 if (details.type() == FIELD && | 544 if (object->map()->unused_property_fields() == 0) { |
551 object->map()->unused_property_fields() == 0) { | |
552 // The properties must be extended before we can store the value. | 545 // The properties must be extended before we can store the value. |
553 // We jump to a runtime call that extends the properties array. | 546 // We jump to a runtime call that extends the properties array. |
554 __ push(receiver_reg); | 547 __ push(receiver_reg); |
555 __ mov(r2, Operand(transition)); | 548 __ mov(r2, Operand(transition)); |
556 __ Push(r2, r0); | 549 __ Push(r2, r0); |
557 __ TailCallExternalReference( | 550 __ TailCallExternalReference( |
558 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 551 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
559 masm->isolate()), | 552 masm->isolate()), |
560 3, | 553 3, |
561 1); | 554 1); |
562 return; | 555 return; |
563 } | 556 } |
564 | 557 |
565 // Update the map of the object. | 558 // Update the map of the object. |
566 __ mov(scratch1, Operand(transition)); | 559 __ mov(scratch1, Operand(transition)); |
567 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 560 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
568 | 561 |
569 // Update the write barrier for the map field and pass the now unused | 562 // Update the write barrier for the map field and pass the now unused |
570 // name_reg as scratch register. | 563 // name_reg as scratch register. |
571 __ RecordWriteField(receiver_reg, | 564 __ RecordWriteField(receiver_reg, |
572 HeapObject::kMapOffset, | 565 HeapObject::kMapOffset, |
573 scratch1, | 566 scratch1, |
574 scratch2, | 567 scratch2, |
575 kLRHasNotBeenSaved, | 568 kLRHasNotBeenSaved, |
576 kDontSaveFPRegs, | 569 kDontSaveFPRegs, |
577 OMIT_REMEMBERED_SET, | 570 OMIT_REMEMBERED_SET, |
578 OMIT_SMI_CHECK); | 571 OMIT_SMI_CHECK); |
579 | 572 |
580 if (details.type() == CONSTANT_FUNCTION) return; | |
581 | |
582 int index = transition->instance_descriptors()->GetFieldIndex( | 573 int index = transition->instance_descriptors()->GetFieldIndex( |
583 transition->LastAdded()); | 574 transition->LastAdded()); |
584 | 575 |
585 // Adjust for the number of properties stored in the object. Even in the | 576 // Adjust for the number of properties stored in the object. Even in the |
586 // face of a transition we can use the old map here because the size of the | 577 // face of a transition we can use the old map here because the size of the |
587 // object and the number of in-object properties is not going to change. | 578 // object and the number of in-object properties is not going to change. |
588 index -= object->map()->inobject_properties(); | 579 index -= object->map()->inobject_properties(); |
589 | 580 |
590 // TODO(verwaest): Share this code as a code stub. | 581 // TODO(verwaest): Share this code as a code stub. |
591 SmiCheck smi_check = representation.IsTagged() | 582 SmiCheck smi_check = representation.IsTagged() |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 bool returns_handle = | 949 bool returns_handle = |
959 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); | 950 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); |
960 ApiFunction fun(function_address); | 951 ApiFunction fun(function_address); |
961 ExternalReference::Type type = | 952 ExternalReference::Type type = |
962 returns_handle ? | 953 returns_handle ? |
963 ExternalReference::DIRECT_API_CALL : | 954 ExternalReference::DIRECT_API_CALL : |
964 ExternalReference::DIRECT_API_CALL_NEW; | 955 ExternalReference::DIRECT_API_CALL_NEW; |
965 ExternalReference ref = ExternalReference(&fun, | 956 ExternalReference ref = ExternalReference(&fun, |
966 type, | 957 type, |
967 masm->isolate()); | 958 masm->isolate()); |
968 Address thunk_address = returns_handle | |
969 ? FUNCTION_ADDR(&InvokeInvocationCallback) | |
970 : FUNCTION_ADDR(&InvokeFunctionCallback); | |
971 ExternalReference::Type thunk_type = | |
972 returns_handle ? | |
973 ExternalReference::PROFILING_API_CALL : | |
974 ExternalReference::PROFILING_API_CALL_NEW; | |
975 ApiFunction thunk_fun(thunk_address); | |
976 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | |
977 masm->isolate()); | |
978 | |
979 AllowExternalCallThatCantCauseGC scope(masm); | 959 AllowExternalCallThatCantCauseGC scope(masm); |
980 __ CallApiFunctionAndReturn(ref, | 960 __ CallApiFunctionAndReturn(ref, |
981 function_address, | |
982 thunk_ref, | |
983 r1, | |
984 kStackUnwindSpace, | 961 kStackUnwindSpace, |
985 returns_handle, | 962 returns_handle, |
986 kFastApiCallArguments + 1); | 963 kFastApiCallArguments + 1); |
987 } | 964 } |
988 | 965 |
989 | 966 |
990 class CallInterceptorCompiler BASE_EMBEDDED { | 967 class CallInterceptorCompiler BASE_EMBEDDED { |
991 public: | 968 public: |
992 CallInterceptorCompiler(StubCompiler* stub_compiler, | 969 CallInterceptorCompiler(StubCompiler* stub_compiler, |
993 const ParameterCount& arguments, | 970 const ParameterCount& arguments, |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 | 1447 |
1471 // Create AccessorInfo instance on the stack above the exit frame with | 1448 // Create AccessorInfo instance on the stack above the exit frame with |
1472 // scratch2 (internal::Object** args_) as the data. | 1449 // scratch2 (internal::Object** args_) as the data. |
1473 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); | 1450 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); |
1474 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& | 1451 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
1475 | 1452 |
1476 const int kStackUnwindSpace = kFastApiCallArguments + 1; | 1453 const int kStackUnwindSpace = kFastApiCallArguments + 1; |
1477 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1454 Address getter_address = v8::ToCData<Address>(callback->getter()); |
1478 bool returns_handle = | 1455 bool returns_handle = |
1479 !CallbackTable::ReturnsVoid(isolate(), getter_address); | 1456 !CallbackTable::ReturnsVoid(isolate(), getter_address); |
1480 | |
1481 ApiFunction fun(getter_address); | 1457 ApiFunction fun(getter_address); |
1482 ExternalReference::Type type = | 1458 ExternalReference::Type type = |
1483 returns_handle ? | 1459 returns_handle ? |
1484 ExternalReference::DIRECT_GETTER_CALL : | 1460 ExternalReference::DIRECT_GETTER_CALL : |
1485 ExternalReference::DIRECT_GETTER_CALL_NEW; | 1461 ExternalReference::DIRECT_GETTER_CALL_NEW; |
| 1462 |
1486 ExternalReference ref = ExternalReference(&fun, type, isolate()); | 1463 ExternalReference ref = ExternalReference(&fun, type, isolate()); |
1487 | |
1488 Address thunk_address = returns_handle | |
1489 ? FUNCTION_ADDR(&InvokeAccessorGetter) | |
1490 : FUNCTION_ADDR(&InvokeAccessorGetterCallback); | |
1491 ExternalReference::Type thunk_type = | |
1492 returns_handle ? | |
1493 ExternalReference::PROFILING_GETTER_CALL : | |
1494 ExternalReference::PROFILING_GETTER_CALL_NEW; | |
1495 ApiFunction thunk_fun(thunk_address); | |
1496 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | |
1497 isolate()); | |
1498 __ CallApiFunctionAndReturn(ref, | 1464 __ CallApiFunctionAndReturn(ref, |
1499 getter_address, | |
1500 thunk_ref, | |
1501 r2, | |
1502 kStackUnwindSpace, | 1465 kStackUnwindSpace, |
1503 returns_handle, | 1466 returns_handle, |
1504 5); | 1467 5); |
1505 } | 1468 } |
1506 | 1469 |
1507 | 1470 |
1508 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1471 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
1509 Register holder_reg, | 1472 Register holder_reg, |
1510 Handle<JSObject> object, | 1473 Handle<JSObject> object, |
1511 Handle<JSObject> interceptor_holder, | 1474 Handle<JSObject> interceptor_holder, |
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3674 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3637 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3675 } | 3638 } |
3676 } | 3639 } |
3677 | 3640 |
3678 | 3641 |
3679 #undef __ | 3642 #undef __ |
3680 | 3643 |
3681 } } // namespace v8::internal | 3644 } } // namespace v8::internal |
3682 | 3645 |
3683 #endif // V8_TARGET_ARCH_ARM | 3646 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |