]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/RegExp.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / RegExp.cpp
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
3 * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
ba379fdc 4 * Copyright (C) 2009 Torch Mobile, Inc.
14957cd0 5 * Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
9dae56ea
A
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include "config.h"
24#include "RegExp.h"
14957cd0 25
9dae56ea 26#include "Lexer.h"
81345200 27#include "JSCInlines.h"
14957cd0 28#include "RegExpCache.h"
93a37866
A
29#include "Yarr.h"
30#include "YarrJIT.h"
9dae56ea 31#include <wtf/Assertions.h>
9dae56ea 32
6fe7ccc8
A
33#define REGEXP_FUNC_TEST_DATA_GEN 0
34
81345200
A
35#if REGEXP_FUNC_TEST_DATA_GEN
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#endif
40
9dae56ea
A
41namespace JSC {
42
ed1e77d3 43const ClassInfo RegExp::s_info = { "RegExp", 0, 0, CREATE_METHOD_TABLE(RegExp) };
14957cd0 44
93a37866 45RegExpFlags regExpFlags(const String& string)
9dae56ea 46{
14957cd0
A
47 RegExpFlags flags = NoFlags;
48
49 for (unsigned i = 0; i < string.length(); ++i) {
6fe7ccc8 50 switch (string[i]) {
14957cd0
A
51 case 'g':
52 if (flags & FlagGlobal)
53 return InvalidFlags;
54 flags = static_cast<RegExpFlags>(flags | FlagGlobal);
55 break;
56
57 case 'i':
58 if (flags & FlagIgnoreCase)
59 return InvalidFlags;
60 flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
61 break;
62
63 case 'm':
64 if (flags & FlagMultiline)
65 return InvalidFlags;
66 flags = static_cast<RegExpFlags>(flags | FlagMultiline);
67 break;
68
69 default:
70 return InvalidFlags;
71 }
72 }
9dae56ea 73
14957cd0
A
74 return flags;
75}
6fe7ccc8
A
76
77#if REGEXP_FUNC_TEST_DATA_GEN
78class RegExpFunctionalTestCollector {
79 // This class is not thread safe.
80protected:
81 static const char* const s_fileName;
82
83public:
84 static RegExpFunctionalTestCollector* get();
85
86 ~RegExpFunctionalTestCollector();
87
93a37866 88 void outputOneTest(RegExp*, String, int, int*, int);
6fe7ccc8
A
89 void clearRegExp(RegExp* regExp)
90 {
91 if (regExp == m_lastRegExp)
92 m_lastRegExp = 0;
93 }
94
95private:
96 RegExpFunctionalTestCollector();
97
93a37866 98 void outputEscapedString(const String&, bool escapeSlash = false);
6fe7ccc8
A
99
100 static RegExpFunctionalTestCollector* s_instance;
101 FILE* m_file;
102 RegExp* m_lastRegExp;
14957cd0
A
103};
104
6fe7ccc8
A
105const char* const RegExpFunctionalTestCollector::s_fileName = "/tmp/RegExpTestsData";
106RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::s_instance = 0;
107
108RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::get()
109{
110 if (!s_instance)
111 s_instance = new RegExpFunctionalTestCollector();
112
113 return s_instance;
114}
115
ed1e77d3 116void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, const String& s, int startOffset, int* ovector, int result)
6fe7ccc8
A
117{
118 if ((!m_lastRegExp) || (m_lastRegExp != regExp)) {
119 m_lastRegExp = regExp;
120 fputc('/', m_file);
93a37866 121 outputEscapedString(regExp->pattern(), true);
6fe7ccc8
A
122 fputc('/', m_file);
123 if (regExp->global())
124 fputc('g', m_file);
125 if (regExp->ignoreCase())
126 fputc('i', m_file);
127 if (regExp->multiline())
128 fputc('m', m_file);
129 fprintf(m_file, "\n");
130 }
131
132 fprintf(m_file, " \"");
93a37866 133 outputEscapedString(s);
6fe7ccc8
A
134 fprintf(m_file, "\", %d, %d, (", startOffset, result);
135 for (unsigned i = 0; i <= regExp->numSubpatterns(); i++) {
136 int subpatternBegin = ovector[i * 2];
137 int subpatternEnd = ovector[i * 2 + 1];
138 if (subpatternBegin == -1)
139 subpatternEnd = -1;
140 fprintf(m_file, "%d, %d", subpatternBegin, subpatternEnd);
141 if (i < regExp->numSubpatterns())
142 fputs(", ", m_file);
143 }
144
145 fprintf(m_file, ")\n");
146 fflush(m_file);
147}
148
149RegExpFunctionalTestCollector::RegExpFunctionalTestCollector()
150{
151 m_file = fopen(s_fileName, "r+");
152 if (!m_file)
153 m_file = fopen(s_fileName, "w+");
154
155 fseek(m_file, 0L, SEEK_END);
156}
157
158RegExpFunctionalTestCollector::~RegExpFunctionalTestCollector()
159{
160 fclose(m_file);
161 s_instance = 0;
162}
163
93a37866 164void RegExpFunctionalTestCollector::outputEscapedString(const String& s, bool escapeSlash)
6fe7ccc8
A
165{
166 int len = s.length();
167
168 for (int i = 0; i < len; ++i) {
169 UChar c = s[i];
170
171 switch (c) {
172 case '\0':
173 fputs("\\0", m_file);
174 break;
175 case '\a':
176 fputs("\\a", m_file);
177 break;
178 case '\b':
179 fputs("\\b", m_file);
180 break;
181 case '\f':
182 fputs("\\f", m_file);
183 break;
184 case '\n':
185 fputs("\\n", m_file);
186 break;
187 case '\r':
188 fputs("\\r", m_file);
189 break;
190 case '\t':
191 fputs("\\t", m_file);
192 break;
193 case '\v':
194 fputs("\\v", m_file);
195 break;
196 case '/':
197 if (escapeSlash)
198 fputs("\\/", m_file);
199 else
200 fputs("/", m_file);
201 break;
202 case '\"':
203 fputs("\\\"", m_file);
204 break;
205 case '\\':
206 fputs("\\\\", m_file);
207 break;
208 case '\?':
209 fputs("\?", m_file);
210 break;
211 default:
212 if (c > 0x7f)
213 fprintf(m_file, "\\u%04x", c);
214 else
215 fputc(c, m_file);
216 break;
217 }
218 }
219}
220#endif
221
93a37866
A
222RegExp::RegExp(VM& vm, const String& patternString, RegExpFlags flags)
223 : JSCell(vm, vm.regExpStructure.get())
14957cd0
A
224 , m_state(NotCompiled)
225 , m_patternString(patternString)
226 , m_flags(flags)
9dae56ea
A
227 , m_constructionError(0)
228 , m_numSubpatterns(0)
14957cd0 229#if ENABLE(REGEXP_TRACING)
81345200
A
230 , m_rtMatchOnlyTotalSubjectStringLen(0.0)
231 , m_rtMatchTotalSubjectStringLen(0.0)
232 , m_rtMatchOnlyCallCount(0)
233 , m_rtMatchOnlyFoundCount(0)
14957cd0
A
234 , m_rtMatchCallCount(0)
235 , m_rtMatchFoundCount(0)
236#endif
9dae56ea 237{
6fe7ccc8
A
238}
239
93a37866 240void RegExp::finishCreation(VM& vm)
6fe7ccc8 241{
93a37866 242 Base::finishCreation(vm);
14957cd0
A
243 Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
244 if (m_constructionError)
245 m_state = ParseError;
246 else
247 m_numSubpatterns = pattern.m_numSubpatterns;
ba379fdc
A
248}
249
6fe7ccc8 250void RegExp::destroy(JSCell* cell)
ba379fdc 251{
93a37866 252 RegExp* thisObject = static_cast<RegExp*>(cell);
6fe7ccc8
A
253#if REGEXP_FUNC_TEST_DATA_GEN
254 RegExpFunctionalTestCollector::get()->clearRegExp(this);
255#endif
256 thisObject->RegExp::~RegExp();
ba379fdc 257}
ba379fdc 258
93a37866 259RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlags flags)
ba379fdc 260{
93a37866
A
261 RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags);
262 regExp->finishCreation(vm);
6fe7ccc8 263 return regExp;
9dae56ea
A
264}
265
93a37866 266RegExp* RegExp::create(VM& vm, const String& patternString, RegExpFlags flags)
6fe7ccc8 267{
93a37866 268 return vm.regExpCache()->lookupOrCreate(patternString, flags);
6fe7ccc8
A
269}
270
93a37866 271void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize)
9dae56ea 272{
14957cd0
A
273 Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
274 if (m_constructionError) {
93a37866 275 RELEASE_ASSERT_NOT_REACHED();
ed1e77d3 276#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
14957cd0
A
277 m_state = ParseError;
278 return;
ed1e77d3 279#endif
14957cd0 280 }
14957cd0 281 ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
ba379fdc 282
6fe7ccc8
A
283 if (!hasCode()) {
284 ASSERT(m_state == NotCompiled);
93a37866 285 vm->regExpCache()->addToStrongCache(this);
6fe7ccc8
A
286 m_state = ByteCode;
287 }
288
ba379fdc 289#if ENABLE(YARR_JIT)
81345200 290 if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
93a37866 291 Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
6fe7ccc8 292 if (!m_regExpJITCode.isFallBack()) {
14957cd0
A
293 m_state = JITCode;
294 return;
295 }
14957cd0 296 }
6fe7ccc8
A
297#else
298 UNUSED_PARAM(charSize);
ba379fdc 299#endif
14957cd0 300
ed1e77d3 301 m_state = ByteCode;
93a37866 302 m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
9dae56ea
A
303}
304
93a37866 305void RegExp::compileIfNecessary(VM& vm, Yarr::YarrCharSize charSize)
ba379fdc 306{
6fe7ccc8
A
307 if (hasCode()) {
308#if ENABLE(YARR_JIT)
309 if (m_state != JITCode)
310 return;
311 if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCode()))
312 return;
313 if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCode()))
314 return;
315#else
316 return;
317#endif
318 }
ba379fdc 319
93a37866 320 compile(&vm, charSize);
6fe7ccc8
A
321}
322
93a37866 323int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int, 32>& ovector)
6fe7ccc8 324{
14957cd0
A
325#if ENABLE(REGEXP_TRACING)
326 m_rtMatchCallCount++;
81345200 327 m_rtMatchTotalSubjectStringLen += (double)(s.length() - startOffset);
14957cd0
A
328#endif
329
6fe7ccc8 330 ASSERT(m_state != ParseError);
93a37866 331 compileIfNecessary(vm, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
ba379fdc 332
6fe7ccc8
A
333 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
334 ovector.resize(offsetVectorSize);
335 int* offsetVector = ovector.data();
14957cd0 336
6fe7ccc8
A
337 int result;
338#if ENABLE(YARR_JIT)
339 if (m_state == JITCode) {
340 if (s.is8Bit())
341 result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length(), offsetVector).start;
342 else
343 result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length(), offsetVector).start;
344#if ENABLE(YARR_JIT_DEBUG)
345 matchCompareWithInterpreter(s, startOffset, offsetVector, result);
346#endif
347 } else
348#endif
349 result = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, reinterpret_cast<unsigned*>(offsetVector));
350
351 // FIXME: The YARR engine should handle unsigned or size_t length matches.
352 // The YARR Interpreter is "unsigned" clean, while the YARR JIT hasn't been addressed.
353 // The offset vector handling needs to change as well.
354 // Right now we convert a match where the offsets overflowed into match failure.
355 // There are two places in WebCore that call the interpreter directly that need to
81345200
A
356 // have their offsets changed to int as well. They are yarr/RegularExpression.cpp
357 // and inspector/ContentSearchUtilities.cpp
6fe7ccc8
A
358 if (s.length() > INT_MAX) {
359 bool overflowed = false;
360
361 if (result < -1)
362 overflowed = true;
363
364 for (unsigned i = 0; i <= m_numSubpatterns; i++) {
365 if ((offsetVector[i*2] < -1) || ((offsetVector[i*2] >= 0) && (offsetVector[i*2+1] < -1))) {
366 overflowed = true;
367 offsetVector[i*2] = -1;
368 offsetVector[i*2+1] = -1;
369 }
ba379fdc
A
370 }
371
6fe7ccc8
A
372 if (overflowed)
373 result = -1;
374 }
375
376 ASSERT(result >= -1);
377
378#if REGEXP_FUNC_TEST_DATA_GEN
379 RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
380#endif
381
382#if ENABLE(REGEXP_TRACING)
383 if (result != -1)
384 m_rtMatchFoundCount++;
385#endif
386
387 return result;
388}
389
93a37866 390void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize)
6fe7ccc8
A
391{
392 Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
393 if (m_constructionError) {
93a37866 394 RELEASE_ASSERT_NOT_REACHED();
ed1e77d3 395#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
6fe7ccc8
A
396 m_state = ParseError;
397 return;
ed1e77d3 398#endif
6fe7ccc8
A
399 }
400 ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
401
402 if (!hasCode()) {
403 ASSERT(m_state == NotCompiled);
93a37866 404 vm->regExpCache()->addToStrongCache(this);
6fe7ccc8
A
405 m_state = ByteCode;
406 }
ba379fdc 407
ba379fdc 408#if ENABLE(YARR_JIT)
81345200 409 if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
93a37866 410 Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
6fe7ccc8
A
411 if (!m_regExpJITCode.isFallBack()) {
412 m_state = JITCode;
413 return;
414 }
6fe7ccc8
A
415 }
416#else
417 UNUSED_PARAM(charSize);
ba379fdc 418#endif
4e4e5a6f 419
ed1e77d3 420 m_state = ByteCode;
93a37866 421 m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
6fe7ccc8
A
422}
423
93a37866 424void RegExp::compileIfNecessaryMatchOnly(VM& vm, Yarr::YarrCharSize charSize)
6fe7ccc8
A
425{
426 if (hasCode()) {
427#if ENABLE(YARR_JIT)
428 if (m_state != JITCode)
429 return;
430 if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCodeMatchOnly()))
431 return;
432 if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCodeMatchOnly()))
433 return;
434#else
435 return;
436#endif
437 }
438
93a37866 439 compileMatchOnly(&vm, charSize);
6fe7ccc8
A
440}
441
93a37866 442MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset)
6fe7ccc8 443{
14957cd0 444#if ENABLE(REGEXP_TRACING)
81345200
A
445 m_rtMatchOnlyCallCount++;
446 m_rtMatchOnlyTotalSubjectStringLen += (double)(s.length() - startOffset);
14957cd0 447#endif
4e4e5a6f 448
6fe7ccc8 449 ASSERT(m_state != ParseError);
93a37866 450 compileIfNecessaryMatchOnly(vm, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
6fe7ccc8
A
451
452#if ENABLE(YARR_JIT)
453 if (m_state == JITCode) {
454 MatchResult result = s.is8Bit() ?
455 m_regExpJITCode.execute(s.characters8(), startOffset, s.length()) :
456 m_regExpJITCode.execute(s.characters16(), startOffset, s.length());
457#if ENABLE(REGEXP_TRACING)
458 if (!result)
81345200 459 m_rtMatchOnlyFoundCount++;
6fe7ccc8 460#endif
ba379fdc
A
461 return result;
462 }
6fe7ccc8
A
463#endif
464
465 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
466 int* offsetVector;
467 Vector<int, 32> nonReturnedOvector;
468 nonReturnedOvector.resize(offsetVectorSize);
469 offsetVector = nonReturnedOvector.data();
470 int r = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, reinterpret_cast<unsigned*>(offsetVector));
471#if REGEXP_FUNC_TEST_DATA_GEN
472 RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
473#endif
474
475 if (r >= 0) {
476#if ENABLE(REGEXP_TRACING)
81345200 477 m_rtMatchOnlyFoundCount++;
6fe7ccc8
A
478#endif
479 return MatchResult(r, reinterpret_cast<unsigned*>(offsetVector)[1]);
480 }
ba379fdc 481
6fe7ccc8 482 return MatchResult::failed();
ba379fdc
A
483}
484
14957cd0 485void RegExp::invalidateCode()
ba379fdc 486{
6fe7ccc8 487 if (!hasCode())
14957cd0
A
488 return;
489 m_state = NotCompiled;
6fe7ccc8
A
490#if ENABLE(YARR_JIT)
491 m_regExpJITCode.clear();
492#endif
ed1e77d3 493 m_regExpBytecode = nullptr;
ba379fdc
A
494}
495
14957cd0 496#if ENABLE(YARR_JIT_DEBUG)
93a37866 497void RegExp::matchCompareWithInterpreter(const String& s, int startOffset, int* offsetVector, int jitResult)
9dae56ea 498{
14957cd0
A
499 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
500 Vector<int, 32> interpreterOvector;
501 interpreterOvector.resize(offsetVectorSize);
502 int* interpreterOffsetVector = interpreterOvector.data();
503 int interpreterResult = 0;
504 int differences = 0;
505
506 // Initialize interpreterOffsetVector with the return value (index 0) and the
507 // first subpattern start indicies (even index values) set to -1.
508 // No need to init the subpattern end indicies.
509 for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
510 interpreterOffsetVector[j] = -1;
511
6fe7ccc8 512 interpreterResult = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, interpreterOffsetVector);
14957cd0
A
513
514 if (jitResult != interpreterResult)
515 differences++;
516
517 for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++)
518 if ((offsetVector[j] != interpreterOffsetVector[j])
519 || ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1])))
520 differences++;
521
522 if (differences) {
93a37866 523 dataLogF("RegExp Discrepency for /%s/\n string input ", pattern().utf8().data());
14957cd0
A
524 unsigned segmentLen = s.length() - static_cast<unsigned>(startOffset);
525
93a37866 526 dataLogF((segmentLen < 150) ? "\"%s\"\n" : "\"%148s...\"\n", s.utf8().data() + startOffset);
14957cd0
A
527
528 if (jitResult != interpreterResult) {
93a37866 529 dataLogF(" JIT result = %d, blah interpreted result = %d\n", jitResult, interpreterResult);
14957cd0 530 differences--;
9dae56ea 531 } else {
93a37866 532 dataLogF(" Correct result = %d\n", jitResult);
9dae56ea
A
533 }
534
14957cd0
A
535 if (differences) {
536 for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++) {
537 if (offsetVector[j] != interpreterOffsetVector[j])
93a37866 538 dataLogF(" JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j, offsetVector[j], j, interpreterOffsetVector[j]);
14957cd0 539 if ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1]))
93a37866 540 dataLogF(" JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j+1, offsetVector[j+1], j+1, interpreterOffsetVector[j+1]);
14957cd0 541 }
9dae56ea 542 }
9dae56ea 543 }
9dae56ea 544}
14957cd0
A
545#endif
546
547#if ENABLE(REGEXP_TRACING)
548 void RegExp::printTraceData()
549 {
550 char formattedPattern[41];
551 char rawPattern[41];
552
553 strncpy(rawPattern, pattern().utf8().data(), 40);
554 rawPattern[40]= '\0';
9dae56ea 555
14957cd0
A
556 int pattLen = strlen(rawPattern);
557
558 snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern);
559
560#if ENABLE(YARR_JIT)
6fe7ccc8 561 Yarr::YarrCodeBlock& codeBlock = m_regExpJITCode;
14957cd0
A
562
563 const size_t jitAddrSize = 20;
81345200
A
564 char jit8BitMatchOnlyAddr[jitAddrSize];
565 char jit16BitMatchOnlyAddr[jitAddrSize];
566 char jit8BitMatchAddr[jitAddrSize];
567 char jit16BitMatchAddr[jitAddrSize];
568 if (m_state == ByteCode) {
569 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "fallback ");
570 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "---- ");
571 snprintf(jit8BitMatchAddr, jitAddrSize, "fallback ");
572 snprintf(jit16BitMatchAddr, jitAddrSize, "---- ");
573 } else {
574 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchOnlyAddr()));
575 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchOnlyAddr()));
576 snprintf(jit8BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchAddr()));
577 snprintf(jit16BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchAddr()));
578 }
14957cd0 579#else
81345200
A
580 const char* jit8BitMatchOnlyAddr = "JIT Off";
581 const char* jit16BitMatchOnlyAddr = "";
582 const char* jit8BitMatchAddr = "JIT Off";
583 const char* jit16BitMatchAddr = "";
ba379fdc 584#endif
81345200
A
585 unsigned averageMatchOnlyStringLen = (unsigned)(m_rtMatchOnlyTotalSubjectStringLen / m_rtMatchOnlyCallCount);
586 unsigned averageMatchStringLen = (unsigned)(m_rtMatchTotalSubjectStringLen / m_rtMatchCallCount);
ba379fdc 587
81345200
A
588 printf("%-40.40s %16.16s %16.16s %10d %10d %10u\n", formattedPattern, jit8BitMatchOnlyAddr, jit16BitMatchOnlyAddr, m_rtMatchOnlyCallCount, m_rtMatchOnlyFoundCount, averageMatchOnlyStringLen);
589 printf(" %16.16s %16.16s %10d %10d %10u\n", jit8BitMatchAddr, jit16BitMatchAddr, m_rtMatchCallCount, m_rtMatchFoundCount, averageMatchStringLen);
14957cd0
A
590 }
591#endif
6fe7ccc8 592
9dae56ea 593} // namespace JSC