Use folly::dynamic::object and folly::dynamic::string exclusivly
[hiphop-php.git] / hphp / runtime / base / shared-string.cpp
blob92092a1f3004f5975034f09c55e579437c20d3a8
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/shared-string.h"
19 namespace HPHP {
20 ///////////////////////////////////////////////////////////////////////////////
22 SharedStringData::InternMap SharedStringData::s_intern;
24 SharedStringData::SharedStringData(const std::string &data) : m_data(data) {
25 m_count = 1;
28 int SharedStringData::decAtomicCount() const {
29 assert(m_count > 0);
30 int cur = m_count.fetch_and_decrement() - 1;
31 if (cur == 0) {
32 // Only left in intern map. While this data is still in the
33 // the map we consider this data dying. All new Creates will
34 // overwrite the SharedStringData* in the slot and not use this one.
35 InternMap::accessor acc;
36 bool found = s_intern.find(acc, m_data);
37 assert(m_count == 0);
38 // May not be found or may not be acc->second if other thread overwrote.
39 // Safe to just delete self.
40 if (found && acc->second == this) {
41 s_intern.erase(acc);
43 return 0;
45 return 1;
48 void SharedStringData::atomicRelease() {
49 delete this;
52 const std::string &SharedStringData::getString() const {
53 return m_data;
56 void SharedStringData::Create(InternMap::accessor &acc,
57 const std::string &data) {
58 if (s_intern.insert(acc, data)) {
59 acc->second = new SharedStringData(acc->first);
60 return;
62 // Danger is now that the data is dying. We must not acquire a reference
63 // if it in that state.
64 while (true) {
65 int cur = acc->second->m_count;
66 if (cur == 0) {
67 acc->second = new SharedStringData(acc->first);
68 break;
70 // Never change refcount of 0 to refcount of 1, impossible
71 // to revive a dying SharedStringData.
72 if (acc->second->m_count.compare_and_swap(cur + 1, cur) == cur) {
73 break;
75 // Other thread must have inc/dec ref'd since we got cur
79 SharedString &SharedString::operator=(const std::string &data) {
80 reset();
81 SharedStringData::InternMap::accessor acc;
82 SharedStringData::Create(acc, data);
83 // Ref count already incremented in Create
84 overwrite_unsafe(acc->second);
85 return *this;
88 ///////////////////////////////////////////////////////////////////////////////