1/*
2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ArrayAllocationProfile.h"
28
29#include "JSCInlines.h"
30
31#include <algorithm>
32
33namespace JSC {
34
35void ArrayAllocationProfile::updateProfile()
36{
37 // This is awkwardly racy but totally sound even when executed concurrently. The
38 // worst cases go something like this:
39 //
40 // - Two threads race to execute this code; one of them succeeds in updating the
41 // m_currentIndexingType and the other either updates it again, or sees a null
42 // m_lastArray; if it updates it again then at worst it will cause the profile
43 // to "forget" some array. That's still sound, since we don't promise that
44 // this profile is a reflection of any kind of truth.
45 //
46 // - A concurrent thread reads m_lastArray, but that array is now dead. While
47 // it's possible for that array to no longer be reachable, it cannot actually
48 // be freed, since we require the GC to wait until all concurrent JITing
49 // finishes.
50 //
51 // But one exception is vector length. We access vector length to get the vector
52 // length hint. However vector length can be accessible only from the main
53 // thread because large butterfly can be realloced in the main thread.
54 // So for now, we update the allocation profile only from the main thread.
55
56 ASSERT(!isCompilationThread());
57 JSArray* lastArray = m_lastArray;
58 if (!lastArray)
59 return;
60 if (LIKELY(Options::useArrayAllocationProfiling())) {
61 // The basic model here is that we will upgrade ourselves to whatever the CoW version of lastArray is except ArrayStorage since we don't have CoW ArrayStorage.
62 IndexingType indexingType = leastUpperBoundOfIndexingTypes(m_currentIndexingType & IndexingTypeMask, lastArray->indexingType());
63 if (isCopyOnWrite(m_currentIndexingType)) {
64 if (indexingType > ArrayWithContiguous)
65 indexingType = ArrayWithContiguous;
66 indexingType |= CopyOnWrite;
67 }
68 m_currentIndexingType = indexingType;
69 m_largestSeenVectorLength = std::min(std::max(m_largestSeenVectorLength, lastArray->getVectorLength()), BASE_CONTIGUOUS_VECTOR_LEN_MAX);
70 }
71 m_lastArray = nullptr;
72}
73
74} // namespace JSC
75
76