OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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_HEAP_SPACES_INL_H_ | 5 #ifndef V8_HEAP_SPACES_INL_H_ |
6 #define V8_HEAP_SPACES_INL_H_ | 6 #define V8_HEAP_SPACES_INL_H_ |
7 | 7 |
8 #include "src/heap/spaces.h" | 8 #include "src/heap/spaces.h" |
9 #include "src/heap-profiler.h" | 9 #include "src/heap-profiler.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) { | 243 HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) { |
244 Address current_top = allocation_info_.top(); | 244 Address current_top = allocation_info_.top(); |
245 Address new_top = current_top + size_in_bytes; | 245 Address new_top = current_top + size_in_bytes; |
246 if (new_top > allocation_info_.limit()) return NULL; | 246 if (new_top > allocation_info_.limit()) return NULL; |
247 | 247 |
248 allocation_info_.set_top(new_top); | 248 allocation_info_.set_top(new_top); |
249 return HeapObject::FromAddress(current_top); | 249 return HeapObject::FromAddress(current_top); |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 HeapObject* PagedSpace::AllocateLinearlyDoubleAlign(int size_in_bytes) { | 253 HeapObject* PagedSpace::AllocateLinearlyAligned(int size_in_bytes, |
| 254 AllocationAlignment alignment) { |
254 Address current_top = allocation_info_.top(); | 255 Address current_top = allocation_info_.top(); |
255 int alignment_size = 0; | 256 int alignment_size = 0; |
256 | 257 |
257 if ((OffsetFrom(current_top) & kDoubleAlignmentMask) != 0) { | 258 if (alignment == kDoubleAligned && |
| 259 (OffsetFrom(current_top) & kDoubleAlignmentMask) != 0) { |
| 260 alignment_size = kPointerSize; |
| 261 size_in_bytes += alignment_size; |
| 262 } else if (alignment == kDoubleUnaligned && |
| 263 (OffsetFrom(current_top) & kDoubleAlignmentMask) == 0) { |
258 alignment_size = kPointerSize; | 264 alignment_size = kPointerSize; |
259 size_in_bytes += alignment_size; | 265 size_in_bytes += alignment_size; |
260 } | 266 } |
261 Address new_top = current_top + size_in_bytes; | 267 Address new_top = current_top + size_in_bytes; |
262 if (new_top > allocation_info_.limit()) return NULL; | 268 if (new_top > allocation_info_.limit()) return NULL; |
263 | 269 |
264 allocation_info_.set_top(new_top); | 270 allocation_info_.set_top(new_top); |
265 if (alignment_size > 0) | 271 if (alignment_size > 0) { |
266 return heap()->EnsureDoubleAligned(HeapObject::FromAddress(current_top), | 272 return heap()->EnsureAligned(HeapObject::FromAddress(current_top), |
267 size_in_bytes); | 273 size_in_bytes, alignment); |
| 274 } |
268 return HeapObject::FromAddress(current_top); | 275 return HeapObject::FromAddress(current_top); |
269 } | 276 } |
270 | 277 |
271 | 278 |
272 // Raw allocation. | 279 // Raw allocation. |
273 AllocationResult PagedSpace::AllocateRaw(int size_in_bytes) { | 280 AllocationResult PagedSpace::AllocateRaw(int size_in_bytes) { |
274 HeapObject* object = AllocateLinearly(size_in_bytes); | 281 HeapObject* object = AllocateLinearly(size_in_bytes); |
275 | 282 |
276 if (object == NULL) { | 283 if (object == NULL) { |
277 object = free_list_.Allocate(size_in_bytes); | 284 object = free_list_.Allocate(size_in_bytes); |
278 if (object == NULL) { | 285 if (object == NULL) { |
279 object = SlowAllocateRaw(size_in_bytes); | 286 object = SlowAllocateRaw(size_in_bytes); |
280 } | 287 } |
281 } | 288 } |
282 | 289 |
283 if (object != NULL) { | 290 if (object != NULL) { |
284 if (identity() == CODE_SPACE) { | 291 if (identity() == CODE_SPACE) { |
285 SkipList::Update(object->address(), size_in_bytes); | 292 SkipList::Update(object->address(), size_in_bytes); |
286 } | 293 } |
287 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes); | 294 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes); |
288 return object; | 295 return object; |
289 } | 296 } |
290 | 297 |
291 return AllocationResult::Retry(identity()); | 298 return AllocationResult::Retry(identity()); |
292 } | 299 } |
293 | 300 |
294 | 301 |
295 // Raw allocation. | 302 // Raw allocation. |
296 AllocationResult PagedSpace::AllocateRawDoubleAligned(int size_in_bytes) { | 303 AllocationResult PagedSpace::AllocateRawAligned(int size_in_bytes, |
| 304 AllocationAlignment alignment) { |
297 DCHECK(identity() == OLD_SPACE); | 305 DCHECK(identity() == OLD_SPACE); |
298 HeapObject* object = AllocateLinearlyDoubleAlign(size_in_bytes); | 306 HeapObject* object = AllocateLinearlyAligned(size_in_bytes, alignment); |
299 int aligned_size_in_bytes = size_in_bytes + kPointerSize; | 307 int aligned_size_in_bytes = size_in_bytes + kPointerSize; |
300 | 308 |
301 if (object == NULL) { | 309 if (object == NULL) { |
302 object = free_list_.Allocate(aligned_size_in_bytes); | 310 object = free_list_.Allocate(aligned_size_in_bytes); |
303 if (object == NULL) { | 311 if (object == NULL) { |
304 object = SlowAllocateRaw(aligned_size_in_bytes); | 312 object = SlowAllocateRaw(aligned_size_in_bytes); |
305 } | 313 } |
306 if (object != NULL) { | 314 if (object != NULL) { |
307 object = heap()->EnsureDoubleAligned(object, aligned_size_in_bytes); | 315 object = heap()->EnsureAligned(object, aligned_size_in_bytes, alignment); |
308 } | 316 } |
309 } | 317 } |
310 | 318 |
311 if (object != NULL) { | 319 if (object != NULL) { |
312 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes); | 320 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes); |
313 return object; | 321 return object; |
314 } | 322 } |
315 | 323 |
316 return AllocationResult::Retry(identity()); | 324 return AllocationResult::Retry(identity()); |
317 } | 325 } |
318 | 326 |
319 | 327 |
320 // ----------------------------------------------------------------------------- | 328 // ----------------------------------------------------------------------------- |
321 // NewSpace | 329 // NewSpace |
322 | 330 |
323 | 331 |
324 AllocationResult NewSpace::AllocateRawDoubleAligned(int size_in_bytes) { | 332 AllocationResult NewSpace::AllocateRawAligned(int size_in_bytes, |
| 333 AllocationAlignment alignment) { |
325 Address old_top = allocation_info_.top(); | 334 Address old_top = allocation_info_.top(); |
326 int alignment_size = 0; | 335 int alignment_size = 0; |
327 int aligned_size_in_bytes = 0; | 336 int aligned_size_in_bytes = 0; |
328 | 337 |
329 // If double alignment is required and top pointer is not aligned, we allocate | 338 // If double alignment is required and top pointer is not aligned, we allocate |
330 // additional memory to take care of the alignment. | 339 // additional memory to take care of the alignment. |
331 if ((OffsetFrom(old_top) & kDoubleAlignmentMask) != 0) { | 340 if (alignment == kDoubleAligned && |
| 341 (OffsetFrom(old_top) & kDoubleAlignmentMask) != 0) { |
| 342 alignment_size += kPointerSize; |
| 343 } else if (alignment == kDoubleUnaligned && |
| 344 (OffsetFrom(old_top) & kDoubleAlignmentMask) == 0) { |
332 alignment_size += kPointerSize; | 345 alignment_size += kPointerSize; |
333 } | 346 } |
334 aligned_size_in_bytes = size_in_bytes + alignment_size; | 347 aligned_size_in_bytes = size_in_bytes + alignment_size; |
335 | 348 |
336 if (allocation_info_.limit() - old_top < aligned_size_in_bytes) { | 349 if (allocation_info_.limit() - old_top < aligned_size_in_bytes) { |
337 return SlowAllocateRaw(size_in_bytes, true); | 350 return SlowAllocateRaw(size_in_bytes, alignment); |
338 } | 351 } |
339 | 352 |
340 HeapObject* obj = HeapObject::FromAddress(old_top); | 353 HeapObject* obj = HeapObject::FromAddress(old_top); |
341 allocation_info_.set_top(allocation_info_.top() + aligned_size_in_bytes); | 354 allocation_info_.set_top(allocation_info_.top() + aligned_size_in_bytes); |
342 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 355 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
343 | 356 |
344 if (alignment_size > 0) { | 357 if (alignment_size > 0) { |
345 obj = heap()->EnsureDoubleAligned(obj, aligned_size_in_bytes); | 358 obj = heap()->PrecedeWithFiller(obj); |
346 } | 359 } |
347 | 360 |
348 // The slow path above ultimately goes through AllocateRaw, so this suffices. | 361 // The slow path above ultimately goes through AllocateRaw, so this suffices. |
349 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); | 362 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); |
350 | 363 |
| 364 DCHECK((kDoubleAligned && (OffsetFrom(obj) & kDoubleAlignmentMask) == 0) || |
| 365 (kDoubleUnaligned && (OffsetFrom(obj) & kDoubleAlignmentMask) != 0)); |
| 366 |
351 return obj; | 367 return obj; |
352 } | 368 } |
353 | 369 |
354 | 370 |
355 AllocationResult NewSpace::AllocateRaw(int size_in_bytes) { | 371 AllocationResult NewSpace::AllocateRaw(int size_in_bytes) { |
356 Address old_top = allocation_info_.top(); | 372 Address old_top = allocation_info_.top(); |
357 | 373 |
358 if (allocation_info_.limit() - old_top < size_in_bytes) { | 374 if (allocation_info_.limit() - old_top < size_in_bytes) { |
359 return SlowAllocateRaw(size_in_bytes, false); | 375 return SlowAllocateRaw(size_in_bytes, kWordAligned); |
360 } | 376 } |
361 | 377 |
362 HeapObject* obj = HeapObject::FromAddress(old_top); | 378 HeapObject* obj = HeapObject::FromAddress(old_top); |
363 allocation_info_.set_top(allocation_info_.top() + size_in_bytes); | 379 allocation_info_.set_top(allocation_info_.top() + size_in_bytes); |
364 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 380 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
365 | 381 |
366 // The slow path above ultimately goes through AllocateRaw, so this suffices. | 382 // The slow path above ultimately goes through AllocateRaw, so this suffices. |
367 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); | 383 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); |
368 | 384 |
369 return obj; | 385 return obj; |
370 } | 386 } |
371 | 387 |
372 | 388 |
373 LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk) { | 389 LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk) { |
374 heap->incremental_marking()->SetOldSpacePageFlags(chunk); | 390 heap->incremental_marking()->SetOldSpacePageFlags(chunk); |
375 return static_cast<LargePage*>(chunk); | 391 return static_cast<LargePage*>(chunk); |
376 } | 392 } |
377 | 393 |
378 | 394 |
379 intptr_t LargeObjectSpace::Available() { | 395 intptr_t LargeObjectSpace::Available() { |
380 return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available()); | 396 return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available()); |
381 } | 397 } |
382 | 398 |
383 } | 399 } |
384 } // namespace v8::internal | 400 } // namespace v8::internal |
385 | 401 |
386 #endif // V8_HEAP_SPACES_INL_H_ | 402 #endif // V8_HEAP_SPACES_INL_H_ |
OLD | NEW |