Let's benchmark malloc
[WebKit-https.git] / PerformanceTests / MallocBench / MallocBench / Interpreter.cpp
1 /*
2  * Copyright (C) 2014 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 "CPUCount.h"
27 #include "Interpreter.h"
28 #include <assert.h>
29 #include <cstddef>
30 #include <cstdlib>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <string>
34 #include <sys/mman.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <sys/uio.h>
38 #include <unistd.h>
39 #include <vector>
40
41 #include "mbmalloc.h"
42
43 Interpreter::Interpreter(const char* fileName)
44 {
45     m_fd = open(fileName, O_RDWR, S_IRUSR | S_IWUSR);
46     if (m_fd == -1)
47         fprintf(stderr, "failed to open\n");
48
49     struct stat buf;
50     fstat(m_fd, &buf);
51
52     m_opCount = buf.st_size / sizeof(Op);
53     assert(m_opCount * sizeof(Op) == buf.st_size);
54
55     size_t maxSlot = 0;
56
57     std::vector<Op> ops(1024);
58     size_t remaining = m_opCount * sizeof(Op);
59     while (remaining) {
60         size_t bytes = std::min(remaining, ops.size() * sizeof(Op));
61         remaining -= bytes;
62         read(m_fd, ops.data(), bytes);
63
64         size_t opCount = bytes / sizeof(Op);
65         for (size_t i = 0; i < opCount; ++i) {
66             Op op = ops[i];
67             if (op.slot > maxSlot)
68                 maxSlot = op.slot;
69         }
70     }
71
72     m_objects.resize(maxSlot + 1);
73 }
74
75 Interpreter::~Interpreter()
76 {
77     int result = close(m_fd);
78     if (result == -1)
79         fprintf(stderr, "failed to close\n");
80 }
81
82 void Interpreter::run()
83 {
84     std::vector<Op> ops(1024);
85     lseek(m_fd, 0, SEEK_SET);
86     size_t remaining = m_opCount * sizeof(Op);
87     while (remaining) {
88         size_t bytes = std::min(remaining, ops.size() * sizeof(Op));
89         remaining -= bytes;
90         read(m_fd, ops.data(), bytes);
91
92         size_t opCount = bytes / sizeof(Op);
93         for (size_t i = 0; i < opCount; ++i) {
94             Op op = ops[i];
95             switch (op.opcode) {
96             case op_a: {
97                 m_objects[op.slot] = { mbmalloc(op.size), op.size };
98                 assert(m_objects[op.slot].object);
99                 bzero(m_objects[op.slot].object, op.size);
100                 break;
101             }
102             case op_d: {
103                 assert(m_objects[op.slot].object);
104                 assert(m_objects[op.slot].size);
105                 mbfree(m_objects[op.slot].object, m_objects[op.slot].size);
106                 m_objects[op.slot] = { 0, 0 };
107                 break;
108             }
109             default: {
110                 fprintf(stderr, "bad opcode: %d\n", op.opcode);
111                 abort();
112                 break;
113             }
114             }
115         }
116     }
117
118     // A recording might not free all of its allocations.
119     for (size_t i = 0; i < m_objects.size(); ++i) {
120         if (!m_objects[i].object)
121             continue;
122         mbfree(m_objects[i].object, m_objects[i].size);
123         m_objects[i] = { 0, 0 };
124     }
125 }