From 1ddaea61be799218f48621cfcc3c76528029d513 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Fri, 1 May 2009 14:37:28 +0000 Subject: [PATCH] Stop inlining of list reallocation in virtual frames. Review URL: http://codereview.chromium.org/100253 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1835 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/list-inl.h | 39 +++++++++++++++++++++++++++------------ src/list.h | 15 +++++++++++++++ src/virtual-frame.cc | 10 ++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/list-inl.h b/src/list-inl.h index 6dbd214d7..e3d251fba 100644 --- a/src/list-inl.h +++ b/src/list-inl.h @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2006-2009 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -38,21 +38,36 @@ void List::Add(const T& element) { if (length_ < capacity_) { data_[length_++] = element; } else { - // Grow the list capacity by 50%, but make sure to let it grow - // even when the capacity is zero (possible initial case). - int new_capacity = 1 + capacity_ + (capacity_ >> 1); - T* new_data = NewData(new_capacity); - memcpy(new_data, data_, capacity_ * sizeof(T)); - // Since the element reference could be an element of the list, - // assign it to the new backing store before deleting the old. - new_data[length_++] = element; - DeleteData(data_); - data_ = new_data; - capacity_ = new_capacity; + List::ResizeAdd(element); } } +// Use two layers of inlining so that the non-inlined function can +// use the same implementation as the inlined version. +template +void List::ResizeAdd(const T& element) { + ResizeAddInternal(element); +} + + +template +void List::ResizeAddInternal(const T& element) { + ASSERT(length_ >= capacity_); + // Grow the list capacity by 50%, but make sure to let it grow + // even when the capacity is zero (possible initial case). + int new_capacity = 1 + capacity_ + (capacity_ >> 1); + T* new_data = List::NewData(new_capacity); + memcpy(new_data, data_, capacity_ * sizeof(T)); + // Since the element reference could be an element of the list, + // assign it to the new backing store before deleting the old. + new_data[length_++] = element; + List::DeleteData(data_); + data_ = new_data; + capacity_ = new_capacity; +} + + template Vector List::AddBlock(T value, int count) { int start = length_; diff --git a/src/list.h b/src/list.h index dc2f1158d..92d23ea39 100644 --- a/src/list.h +++ b/src/list.h @@ -118,9 +118,24 @@ class List { INLINE(T* NewData(int n)) { return static_cast(P::New(n * sizeof(T))); } INLINE(void DeleteData(T* data)) { P::Delete(data); } + // Increase the capacity of a full list, and add an element. + // List must be full already. + void ResizeAdd(const T& element); + + // Inlined implementation of ResizeAdd, shared by inlined and + // non-inlined versions of ResizeAdd. + void ResizeAddInternal(const T& element); + DISALLOW_COPY_AND_ASSIGN(List); }; +class FrameElement; + +// Add() is inlined, ResizeAdd() called by Add() is inlined except for +// Lists of FrameElements, and ResizeAddInternal() is inlined in ResizeAdd(). +template <> +void List::ResizeAdd(const FrameElement& element); } } // namespace v8::internal diff --git a/src/virtual-frame.cc b/src/virtual-frame.cc index cef1d8073..566fcdbc0 100644 --- a/src/virtual-frame.cc +++ b/src/virtual-frame.cc @@ -507,4 +507,14 @@ bool VirtualFrame::Equals(VirtualFrame* other) { return true; } + +// Specialization of List::ResizeAdd to non-inlined version for FrameElements. +// The function ResizeAdd becomes a real function, whose implementation is the +// inlined ResizeAddInternal. +template <> +void List::ResizeAdd(const FrameElement& element) { + ResizeAddInternal(element); +} + } } // namespace v8::internal -- 2.34.1