1668N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A// Implementation of StubQueue 0N/A// Standard wrap-around queue implementation; the queue dimensions 0N/A// are specified by the _queue_begin & _queue_end indices. The queue 0N/A// can be in two states (transparent to the outside): 0N/A// a) contiguous state: all queue entries in one block (or empty) 0N/A// Queue: |...|XXXXXXX|...............| 0N/A// ^0 ^begin ^end ^size = limit 0N/A// b) non-contiguous state: queue entries in two blocks 0N/A// Queue: |XXX|.......|XXXXXXX|.......| 0N/A// ^0 ^end ^begin ^limit ^size 0N/A// 1st block 2nd block 0N/A// In the non-contiguous state, the wrap-around point is 0N/A// indicated via the _buffer_limit index since the last 0N/A// queue entry may not fill up the queue completely in 0N/A// which case we need to know where the 2nd block's end 0N/A// is to do the proper wrap-around. When removing the 0N/A// last entry of the 2nd block, _buffer_limit is reset 0N/A// CAUTION: DO NOT MESS WITH THIS CODE IF YOU CANNOT PROVE 0N/A// ITS CORRECTNESS! THIS CODE IS MORE SUBTLE THAN IT LOOKS! 0N/A // Note: Currently StubQueues are never destroyed so nothing needs to be done here. 0N/A // If we want to implement the destructor, we need to release the BufferBlob 0N/A // allocated in the constructor (i.e., we need to keep it around or look it 0N/A // up via CodeCache::find_blob(...). 0N/A // Queue: |...|XXXXXXX|.............| 0N/A // ^0 ^begin ^end ^size = limit 0N/A // code fits in at the end => nothing to do 0N/A // stub doesn't fit in at the queue end 0N/A // => reduce buffer limit & wrap around 0N/A // Queue: |XXX|.......|XXXXXXX|.......| 0N/A // ^0 ^end ^begin ^limit ^size 0N/A // Not enough space left 0N/A // => reset queue indices 0N/A // buffer limit reached 0N/A // => reset buffer limit & wrap around 0N/A // verify only if initialized 0N/A // verify index boundaries