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