1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Internal implementation of a size-limited quarantine. This file is not
16 : // meant to be included directly.
17 :
18 : #ifndef SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_IMPL_H_
19 : #define SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_IMPL_H_
20 :
21 : namespace agent {
22 : namespace asan {
23 : namespace quarantines {
24 :
25 : template<typename OT, typename SFT>
26 : bool SizeLimitedQuarantineImpl<OT, SFT>::Push(
27 E : const Object& object) {
28 E : size_t size = size_functor_(object);
29 E : if (max_object_size_ != kUnboundedSize && size > max_object_size_)
30 E : return false;
31 E : if (max_quarantine_size_ != kUnboundedSize && size > max_quarantine_size_)
32 i : return false;
33 E : if (!PushImpl(object))
34 i : return false;
35 :
36 E : ScopedQuarantineSizeCountLock size_count_lock(size_count_);
37 E : size_count_.Increment(static_cast<int32>(size), 1);
38 :
39 E : return true;
40 E : }
41 :
42 : template<typename OT, typename SFT>
43 : bool SizeLimitedQuarantineImpl<OT, SFT>::Pop(
44 E : Object* object) {
45 E : DCHECK_NE(static_cast<Object*>(NULL), object);
46 :
47 E : if (max_quarantine_size_ == kUnboundedSize)
48 i : return false;
49 :
50 : {
51 E : ScopedQuarantineSizeCountLock size_count_lock(size_count_);
52 E : if (size_count_.size() <= max_quarantine_size_)
53 E : return false;
54 E : }
55 :
56 E : if (!PopImpl(object))
57 i : return false;
58 :
59 E : size_t size = size_functor_(*object);
60 E : ScopedQuarantineSizeCountLock size_count_lock(size_count_);
61 E : size_count_.Increment(-static_cast<int32>(size), -1);
62 :
63 E : return true;
64 E : }
65 :
66 : template<typename OT, typename SFT>
67 : void SizeLimitedQuarantineImpl<OT, SFT>::Empty(
68 E : ObjectVector* objects) {
69 E : DCHECK_NE(static_cast<ObjectVector*>(NULL), objects);
70 E : EmptyImpl(objects);
71 :
72 : // In order for the quarantine to remain long-term consistent we need to
73 : // remove a size and count consistent with the output of EmptyImpl. Simply
74 : // setting the size and count to zero could introduce inconsistency, as they
75 : // may not yet reflect the contributions of some of the elements returned by
76 : // EmptyImpl.
77 E : int32 net_size = 0;
78 E : for (size_t i = 0; i < objects->size(); ++i) {
79 E : size_t size = size_functor_(objects->at(i));
80 E : net_size += size;
81 E : }
82 :
83 E : ScopedQuarantineSizeCountLock size_count_lock(size_count_);
84 E : size_count_.Increment(-net_size, -static_cast<int32>(objects->size()));
85 E : }
86 :
87 : template<typename OT, typename SFT>
88 E : size_t SizeLimitedQuarantineImpl<OT, SFT>::GetCount() {
89 E : ScopedQuarantineSizeCountLock size_count_lock(size_count_);
90 E : return size_count_.count();
91 E : }
92 :
93 : template<typename OT, typename SFT>
94 : size_t SizeLimitedQuarantineImpl<OT, SFT>::GetLockId(
95 E : const Object& object) {
96 E : return GetLockIdImpl(object);
97 E : }
98 :
99 : template<typename OT, typename SFT>
100 E : void SizeLimitedQuarantineImpl<OT, SFT>::Lock(size_t id) {
101 E : LockImpl(id);
102 E : }
103 :
104 : template<typename OT, typename SFT>
105 E : void SizeLimitedQuarantineImpl<OT, SFT>::Unlock(size_t id) {
106 E : UnlockImpl(id);
107 E : }
108 :
109 : } // namespace quarantines
110 : } // namespace asan
111 : } // namespace agent
112 :
113 : #endif // SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_IMPL_H_
|