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

Side by Side Diff: runtime/vm/object.cc

Issue 1850653003: Provide ability to patch external functions in a class that has already been finalized. The follow… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: sync Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 Isolate* isolate = Isolate::Current(); 2772 Isolate* isolate = Isolate::Current();
2773 const bool changed = trace_allocation != this->TraceAllocation(isolate); 2773 const bool changed = trace_allocation != this->TraceAllocation(isolate);
2774 if (changed) { 2774 if (changed) {
2775 ClassTable* class_table = isolate->class_table(); 2775 ClassTable* class_table = isolate->class_table();
2776 class_table->SetTraceAllocationFor(id(), trace_allocation); 2776 class_table->SetTraceAllocationFor(id(), trace_allocation);
2777 DisableAllocationStub(); 2777 DisableAllocationStub();
2778 } 2778 }
2779 } 2779 }
2780 2780
2781 2781
2782 bool Class::ValidatePostFinalizePatch(const Class& orig_class,
2783 Error* error) const {
2784 ASSERT(error != NULL);
2785 // Not allowed to add new fields in a post finalization patch.
2786 if (fields() != Object::empty_array().raw()) {
2787 *error = LanguageError::NewFormatted(
2788 *error, // No previous error.
2789 Script::Handle(script()),
2790 token_pos(),
2791 Report::AtLocation,
2792 Report::kError,
2793 Heap::kNew,
2794 "new fields are not allowed for this patch");
2795 return false;
2796 }
2797 // There seem to be no functions, the patch is pointless.
2798 if (functions() == Object::empty_array().raw()) {
2799 *error = LanguageError::NewFormatted(
2800 *error, // No previous error.
2801 Script::Handle(script()),
2802 token_pos(),
2803 Report::AtLocation,
2804 Report::kError,
2805 Heap::kNew,
2806 "no functions to patch");
2807 return false;
2808 }
2809 // Iterate over all functions that will be patched and make sure
2810 // the original function was declared 'external' and has not executed
2811 // so far i.e no code has been generated for it.
2812 Thread* thread = Thread::Current();
2813 ASSERT(thread->IsMutatorThread());
2814 Zone* zone = thread->zone();
2815 const Array& funcs = Array::Handle(zone, functions());
2816 Function& func = Function::Handle(zone);
2817 Function& orig_func = Function::Handle(zone);
2818 String& name = String::Handle(zone);
2819 for (intptr_t i = 0; i < funcs.Length(); i++) {
2820 func ^= funcs.At(i);
2821 name ^= func.name();
2822 orig_func ^= orig_class.LookupFunctionAllowPrivate(name);
2823 if (!orig_func.IsNull()) {
2824 if (!orig_func.is_external() || orig_func.HasCode()) {
2825 // We can only patch external functions in a post finalized class.
2826 *error = LanguageError::NewFormatted(
2827 *error, // No previous error.
2828 Script::Handle(script()),
2829 token_pos(),
2830 Report::AtLocation,
2831 Report::kError,
2832 Heap::kNew,
2833 "only external functions that have not executed "
2834 "so far can be patched '%s'", name.ToCString());
regis 2016/03/31 18:16:49 The error message is not quite a correct sentence
siva 2016/03/31 23:48:08 Done.
2835 return false;
2836 }
2837 } else if (!Library::IsPrivate(name)) {
2838 // We can only have new private functions that are added.
2839 *error = LanguageError::NewFormatted(
2840 *error, // No previous error.
2841 Script::Handle(script()),
2842 token_pos(),
2843 Report::AtLocation,
2844 Report::kError,
2845 Heap::kNew,
2846 "only private new functions are allowed '%s'", name.ToCString());
regis 2016/03/31 18:16:49 ditto "'%s' is not private and therefore cannot be
siva 2016/03/31 23:48:08 Done.
2847 return false;
2848 }
2849 }
2850 return true;
2851 }
2852
2853
2782 void Class::set_cha_codes(const Array& cache) const { 2854 void Class::set_cha_codes(const Array& cache) const {
2783 StorePointer(&raw_ptr()->cha_codes_, cache.raw()); 2855 StorePointer(&raw_ptr()->cha_codes_, cache.raw());
2784 } 2856 }
2785 2857
2786 2858
2787 // Apply the members from the patch class to the original class. 2859 // Apply the members from the patch class to the original class.
2788 bool Class::ApplyPatch(const Class& patch, Error* error) const { 2860 bool Class::ApplyPatch(const Class& patch, Error* error) const {
2789 ASSERT(error != NULL); 2861 ASSERT(error != NULL);
2790 ASSERT(!is_finalized()); 2862 ASSERT(!is_finalized());
2791 // Shared handles used during the iteration. 2863 // Shared handles used during the iteration.
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 } 3487 }
3416 3488
3417 3489
3418 void Class::set_is_finalized() const { 3490 void Class::set_is_finalized() const {
3419 ASSERT(!is_finalized()); 3491 ASSERT(!is_finalized());
3420 set_state_bits(ClassFinalizedBits::update(RawClass::kFinalized, 3492 set_state_bits(ClassFinalizedBits::update(RawClass::kFinalized,
3421 raw_ptr()->state_bits_)); 3493 raw_ptr()->state_bits_));
3422 } 3494 }
3423 3495
3424 3496
3497 void Class::SetRefinalize() const {
3498 ASSERT(!IsTopLevel());
3499 set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalize,
3500 raw_ptr()->state_bits_));
3501 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_));
3502 }
3503
3504
3425 void Class::ResetFinalization() const { 3505 void Class::ResetFinalization() const {
3426 ASSERT(IsTopLevel()); 3506 ASSERT(IsTopLevel());
3427 set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated, 3507 set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated,
3428 raw_ptr()->state_bits_)); 3508 raw_ptr()->state_bits_));
3429 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); 3509 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_));
3430 } 3510 }
3431 3511
3432 3512
3433 void Class::set_is_prefinalized() const { 3513 void Class::set_is_prefinalized() const {
3434 ASSERT(!is_finalized()); 3514 ASSERT(!is_finalized());
(...skipping 2390 matching lines...) Expand 10 before | Expand all | Expand 10 after
5825 5905
5826 void Function::SetIsNativeAutoSetupScope(bool value) const { 5906 void Function::SetIsNativeAutoSetupScope(bool value) const {
5827 ASSERT(is_native()); 5907 ASSERT(is_native());
5828 set_is_optimizable(value); 5908 set_is_optimizable(value);
5829 } 5909 }
5830 5910
5831 5911
5832 bool Function::CanBeInlined() const { 5912 bool Function::CanBeInlined() const {
5833 Thread* thread = Thread::Current(); 5913 Thread* thread = Thread::Current();
5834 return is_inlinable() && 5914 return is_inlinable() &&
5915 !is_external() &&
5835 !is_generated_body() && 5916 !is_generated_body() &&
5836 (!FLAG_support_debugger || 5917 (!FLAG_support_debugger ||
5837 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); 5918 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()));
5838 } 5919 }
5839 5920
5840 5921
5841 intptr_t Function::NumParameters() const { 5922 intptr_t Function::NumParameters() const {
5842 return num_fixed_parameters() + NumOptionalParameters(); 5923 return num_fixed_parameters() + NumOptionalParameters();
5843 } 5924 }
5844 5925
(...skipping 15928 matching lines...) Expand 10 before | Expand all | Expand 10 after
21773 return UserTag::null(); 21854 return UserTag::null();
21774 } 21855 }
21775 21856
21776 21857
21777 const char* UserTag::ToCString() const { 21858 const char* UserTag::ToCString() const {
21778 const String& tag_label = String::Handle(label()); 21859 const String& tag_label = String::Handle(label());
21779 return tag_label.ToCString(); 21860 return tag_label.ToCString();
21780 } 21861 }
21781 21862
21782 } // namespace dart 21863 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698