Arquivos
hhvm/hphp/runtime/vm/translator/test/fixup_map.cpp
T
2013-02-19 06:57:54 -08:00

93 linhas
2.9 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "runtime/vm/translator/fixup.h"
#include <gtest/gtest.h>
#include "hhvm/process_init.h"
namespace HPHP { namespace VM { namespace Transl {
//////////////////////////////////////////////////////////////////////
namespace {
constexpr int kNumReaders = 7;
constexpr int kNumToCheck = 50 * 1000;
constexpr int kSpMul = 13;
constexpr int kPcMul = 17;
void* writer(void* that) {
// Give the readers time to wind up.
usleep(1000);
FixupMap* m = (FixupMap*)that;
for (int i = 1; i < kNumToCheck; i++) {
Fixup fxp(kPcMul * i, kSpMul * i);
m->recordFixup(TCA(uintptr_t(i)), fxp);
}
return nullptr;
}
void* reader(void* that) {
FixupMap* m = (FixupMap*)that;
const StringData* sd = StringData::GetStaticString("test");
// ar2: a mock actrec, requires a Func, which can't be builtin.
Unit u;
Func f(u, 1, 1, 1, 0, 0, sd, AttrNone, true, nullptr, 0, false);
ActRec ar2;
ar2.m_savedRip = 0xdeadbeef;
ar2.m_savedRbp = 0;
ar2.m_func = &f;
for (int i = 1; i < kNumToCheck; i++) {
// ar1(i) -> ar2(DONTCARE) -> NULL
ActRec ar1;
ar1.m_savedRbp = (uint64_t)&ar2;
ar1.m_savedRip = i;
FixupMap::VMRegs vmr = { 0, 0, 0 };
while (!m->getFrameRegs(&ar1, 0, &vmr)) {
// Has to succeed eventually.
}
assert(vmr.m_pc == u.entry() + i * kPcMul);
assert(vmr.m_fp == &ar2);
assert(vmr.m_sp == (TypedValue*)&ar2 - i * kSpMul);
}
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////
/*
* Hammer a fixup map with a bunch of concurrent readers and hope it
* works.
*/
TEST(FixupMap, Concurrent) {
FixupMap m;
void* vm = (void*)&m;
pthread_t threads[kNumReaders];
for (int i = 0; i < kNumReaders; i++) {
pthread_create(&threads[i], nullptr, reader, vm);
}
writer(vm);
for (int i = 0; i < kNumReaders; i++) {
pthread_join(threads[i], nullptr);
}
}
//////////////////////////////////////////////////////////////////////
}}}