1/*
2 * Copyright (C) 2016-2017 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 "WasmSignature.h"
28
29#if ENABLE(WEBASSEMBLY)
30
31#include "WasmSignatureInlines.h"
32#include <wtf/FastMalloc.h>
33#include <wtf/HashFunctions.h>
34#include <wtf/PrintStream.h>
35#include <wtf/text/WTFString.h>
36
37namespace JSC { namespace Wasm {
38
39namespace {
40namespace WasmSignatureInternal {
41static const bool verbose = false;
42}
43}
44
45SignatureInformation* SignatureInformation::theOne { nullptr };
46std::once_flag SignatureInformation::signatureInformationFlag;
47
48String Signature::toString() const
49{
50 String result(makeString(returnType()));
51 result.append(" (");
52 for (SignatureArgCount arg = 0; arg < argumentCount(); ++arg) {
53 if (arg)
54 result.append(", ");
55 result.append(makeString(argument(arg)));
56 }
57 result.append(')');
58 return result;
59}
60
61void Signature::dump(PrintStream& out) const
62{
63 out.print(toString());
64}
65
66unsigned Signature::hash() const
67{
68 unsigned accumulator = 0xa1bcedd8u;
69 for (uint32_t i = 0; i < argumentCount(); ++i)
70 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(argument(i))));
71 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(returnType())));
72 return accumulator;
73}
74
75RefPtr<Signature> Signature::tryCreate(SignatureArgCount argumentCount)
76{
77 // We use WTF_MAKE_FAST_ALLOCATED for this class.
78 auto result = tryFastMalloc(allocatedSize(argumentCount));
79 void* memory = nullptr;
80 if (!result.getValue(memory))
81 return nullptr;
82 Signature* signature = new (NotNull, memory) Signature(argumentCount);
83 return adoptRef(signature);
84}
85
86SignatureInformation::SignatureInformation()
87{
88}
89
90Ref<Signature> SignatureInformation::adopt(Ref<Signature>&& signature)
91{
92 SignatureInformation& info = singleton();
93 LockHolder lock(info.m_lock);
94
95 SignatureIndex nextValue = signature->index();
96 auto addResult = info.m_signatureSet.add(SignatureHash { signature.copyRef() });
97 if (addResult.isNewEntry) {
98 if (WasmSignatureInternal::verbose)
99 dataLogLn("Adopt new signature ", signature.get(), " with index ", nextValue, " hash: ", signature->hash());
100 return WTFMove(signature);
101 }
102 nextValue = addResult.iterator->key->index();
103 if (WasmSignatureInternal::verbose)
104 dataLogLn("Existing signature ", signature.get(), " with index ", nextValue, " hash: ", signature->hash());
105 return Ref<Signature>(*addResult.iterator->key);
106}
107
108void SignatureInformation::tryCleanup()
109{
110 SignatureInformation& info = singleton();
111 LockHolder lock(info.m_lock);
112
113 info.m_signatureSet.removeIf([&] (auto& hash) {
114 const auto& signature = hash.key;
115 return signature->refCount() == 1;
116 });
117}
118
119} } // namespace JSC::Wasm
120
121#endif // ENABLE(WEBASSEMBLY)
122