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

Side by Side Diff: src/objects-visiting.h

Issue 391693002: In-object double fields unboxing (for 64-bit only). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 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 #ifndef V8_OBJECTS_VISITING_H_ 5 #ifndef V8_OBJECTS_VISITING_H_
6 #define V8_OBJECTS_VISITING_H_ 6 #define V8_OBJECTS_VISITING_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 9
10 // This file provides base classes and auxiliary methods for defining 10 // This file provides base classes and auxiliary methods for defining
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 kVisitJSObject = kVisitJSObject2, 97 kVisitJSObject = kVisitJSObject2,
98 kVisitStruct = kVisitStruct2, 98 kVisitStruct = kVisitStruct2,
99 kMinObjectSizeInWords = 2 99 kMinObjectSizeInWords = 2
100 }; 100 };
101 101
102 // Visitor ID should fit in one byte. 102 // Visitor ID should fit in one byte.
103 STATIC_ASSERT(kVisitorIdCount <= 256); 103 STATIC_ASSERT(kVisitorIdCount <= 256);
104 104
105 // Determine which specialized visitor should be used for given instance type 105 // Determine which specialized visitor should be used for given instance type
106 // and instance type. 106 // and instance type.
107 static VisitorId GetVisitorId(int instance_type, int instance_size); 107 static VisitorId GetVisitorId(int instance_type, int instance_size,
108 bool has_non_tagged_fields);
108 109
109 static VisitorId GetVisitorId(Map* map) { 110 static VisitorId GetVisitorId(Map* map) {
110 return GetVisitorId(map->instance_type(), map->instance_size()); 111 return GetVisitorId(map->instance_type(), map->instance_size(),
112 FLAG_unbox_double_fields &&
113 !map->layout_descriptor()->IsFastPointerLayout());
111 } 114 }
112 115
113 // For visitors that allow specialization by size calculate VisitorId based 116 // For visitors that allow specialization by size calculate VisitorId based
114 // on size, base visitor id and generic visitor id. 117 // on size, base visitor id and generic visitor id.
115 static VisitorId GetVisitorIdForSize(VisitorId base, 118 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
116 VisitorId generic, 119 int object_size,
117 int object_size) { 120 bool has_non_tagged_fields) {
118 ASSERT((base == kVisitDataObject) || 121 ASSERT((base == kVisitDataObject) ||
119 (base == kVisitStruct) || 122 (base == kVisitStruct) ||
120 (base == kVisitJSObject)); 123 (base == kVisitJSObject));
121 ASSERT(IsAligned(object_size, kPointerSize)); 124 ASSERT(IsAligned(object_size, kPointerSize));
122 ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size); 125 ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size);
123 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); 126 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
127 ASSERT(!has_non_tagged_fields || (base == kVisitJSObject));
128
129 if (has_non_tagged_fields) return generic;
124 130
125 const VisitorId specialization = static_cast<VisitorId>( 131 const VisitorId specialization = static_cast<VisitorId>(
126 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); 132 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords);
127 133
128 return Min(specialization, generic); 134 return Min(specialization, generic);
129 } 135 }
130 }; 136 };
131 137
132 138
133 template<typename Callback> 139 template<typename Callback>
(...skipping 20 matching lines...) Expand all
154 ASSERT(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. 160 ASSERT(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned.
155 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); 161 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
156 } 162 }
157 163
158 template<typename Visitor, 164 template<typename Visitor,
159 StaticVisitorBase::VisitorId base, 165 StaticVisitorBase::VisitorId base,
160 StaticVisitorBase::VisitorId generic, 166 StaticVisitorBase::VisitorId generic,
161 int object_size_in_words> 167 int object_size_in_words>
162 void RegisterSpecialization() { 168 void RegisterSpecialization() {
163 static const int size = object_size_in_words * kPointerSize; 169 static const int size = object_size_in_words * kPointerSize;
164 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size), 170 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false),
165 &Visitor::template VisitSpecialized<size>); 171 &Visitor::template VisitSpecialized<size>);
166 } 172 }
167 173
168 174
169 template<typename Visitor, 175 template<typename Visitor,
170 StaticVisitorBase::VisitorId base, 176 StaticVisitorBase::VisitorId base,
171 StaticVisitorBase::VisitorId generic> 177 StaticVisitorBase::VisitorId generic>
172 void RegisterSpecializations() { 178 void RegisterSpecializations() {
173 STATIC_ASSERT( 179 STATIC_ASSERT(
174 (generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 10); 180 (generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 10);
(...skipping 13 matching lines...) Expand all
188 }; 194 };
189 195
190 196
191 template<typename StaticVisitor> 197 template<typename StaticVisitor>
192 class BodyVisitorBase : public AllStatic { 198 class BodyVisitorBase : public AllStatic {
193 public: 199 public:
194 INLINE(static void IteratePointers(Heap* heap, 200 INLINE(static void IteratePointers(Heap* heap,
195 HeapObject* object, 201 HeapObject* object,
196 int start_offset, 202 int start_offset,
197 int end_offset)) { 203 int end_offset)) {
198 Object** start_slot = reinterpret_cast<Object**>(object->address() + 204 ASSERT(!FLAG_unbox_double_fields ||
199 start_offset); 205 object->map()->layout_descriptor()->IsFastPointerLayout());
200 Object** end_slot = reinterpret_cast<Object**>(object->address() + 206 IterateRawPointers(heap, object, start_offset, end_offset);
201 end_offset); 207 }
202 StaticVisitor::VisitPointers(heap, start_slot, end_slot); 208
209 INLINE(static void IterateBody(Heap* heap, HeapObject* object,
210 int start_offset, int end_offset)) {
211 if (!FLAG_unbox_double_fields ||
212 object->map()->layout_descriptor()->IsFastPointerLayout()) {
213 IterateRawPointers(heap, object, start_offset, end_offset);
214 } else {
215 IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset);
216 }
217 }
218
219 private:
220 INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object,
221 int start_offset, int end_offset)) {
222 StaticVisitor::VisitPointers(heap,
223 HeapObject::RawField(object, start_offset),
224 HeapObject::RawField(object, end_offset));
225 }
226
227 static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object,
228 int start_offset,
229 int end_offset) {
230 ASSERT(FLAG_unbox_double_fields);
231 ASSERT(IsAligned(start_offset, kPointerSize) &&
232 IsAligned(end_offset, kPointerSize));
233
234 InobjectPropertiesHelper helper(object->map());
235 ASSERT(!helper.all_fields_tagged());
236
237 for (int offset = start_offset; offset < end_offset;
238 offset += kPointerSize) {
239 // Visit tagged fields only.
240 if (helper.IsTagged(offset)) {
241 IterateRawPointers(heap, object, offset, offset + kPointerSize);
242 }
243 }
203 } 244 }
204 }; 245 };
205 246
206 247
207 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 248 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
208 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { 249 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> {
209 public: 250 public:
210 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 251 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
211 int object_size = BodyDescriptor::SizeOf(map, object); 252 int object_size = BodyDescriptor::SizeOf(map, object);
212 BodyVisitorBase<StaticVisitor>::IteratePointers( 253 BodyVisitorBase<StaticVisitor>::IterateBody(
213 map->GetHeap(), 254 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
214 object,
215 BodyDescriptor::kStartOffset,
216 object_size);
217 return static_cast<ReturnType>(object_size); 255 return static_cast<ReturnType>(object_size);
218 } 256 }
219 257
220 template<int object_size> 258 template<int object_size>
221 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { 259 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
222 ASSERT(BodyDescriptor::SizeOf(map, object) == object_size); 260 ASSERT(BodyDescriptor::SizeOf(map, object) == object_size);
223 BodyVisitorBase<StaticVisitor>::IteratePointers( 261 BodyVisitorBase<StaticVisitor>::IteratePointers(
224 map->GetHeap(), 262 map->GetHeap(),
225 object, 263 object,
226 BodyDescriptor::kStartOffset, 264 BodyDescriptor::kStartOffset,
227 object_size); 265 object_size);
228 return static_cast<ReturnType>(object_size); 266 return static_cast<ReturnType>(object_size);
229 } 267 }
230 }; 268 };
231 269
232 270
233 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 271 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
234 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { 272 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> {
235 public: 273 public:
236 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 274 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
237 BodyVisitorBase<StaticVisitor>::IteratePointers( 275 BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object,
238 map->GetHeap(), 276 BodyDescriptor::kStartOffset,
239 object, 277 BodyDescriptor::kEndOffset);
240 BodyDescriptor::kStartOffset,
241 BodyDescriptor::kEndOffset);
242 return static_cast<ReturnType>(BodyDescriptor::kSize); 278 return static_cast<ReturnType>(BodyDescriptor::kSize);
243 } 279 }
244 }; 280 };
245 281
246 282
247 // Base class for visitors used for a linear new space iteration. 283 // Base class for visitors used for a linear new space iteration.
248 // IterateBody returns size of visited object. 284 // IterateBody returns size of visited object.
249 // Certain types of objects (i.e. Code objects) are not handled 285 // Certain types of objects (i.e. Code objects) are not handled
250 // by dispatch table of this visitor because they cannot appear 286 // by dispatch table of this visitor because they cannot appear
251 // in the new space. 287 // in the new space.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 // the next element. Given the head of the list, this function removes dead 503 // the next element. Given the head of the list, this function removes dead
468 // elements from the list and if requested records slots for next-element 504 // elements from the list and if requested records slots for next-element
469 // pointers. The template parameter T is a WeakListVisitor that defines how to 505 // pointers. The template parameter T is a WeakListVisitor that defines how to
470 // access the next-element pointers. 506 // access the next-element pointers.
471 template <class T> 507 template <class T>
472 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); 508 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer);
473 509
474 } } // namespace v8::internal 510 } } // namespace v8::internal
475 511
476 #endif // V8_OBJECTS_VISITING_H_ 512 #endif // V8_OBJECTS_VISITING_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698