New smart_malloc/free api for variable-size smart-allocation. Memory allocated with smart_malloc can be freed with smart_free, but otherwise is swept at request-end. Allocations underl0 1K are bump-allocated from slabs with an 8-byte header. Over 1K are routed to malloc with a 16-byte header (doubly-linked list). ZendArray, VectorArray, HphpArray refactored to use smart_malloc instead of a bunch of storage-segregated size classes.
…lect not available Removes the need to patch libcurl and build a copy explicitly for HipHop. If libcurl >= 7.28.0 we get the new curl_multi_wait() function. If not, we either get the patched in curl_multi_select(), or a fallback which works for FDs < 1024, but fails (with an error message) for sites which use more concurrent FDs.
DebuggerClient attempted to avoid problems with destructing Socket objects by calling incPersistent so they would not be swept. However, the semantics of incPersistent apparently require that the object only is persistent in some sort of thread-local cache (it is re-added to the sweepable list for the same thread immediately). When we disconnect the debugger, the DebuggerClient is deleted and the socket object is also destructed---the Sweepable destructor tries to remove it from the current thread's list, so if this is a different thread, the next sweep loop on the original creating thread will make function calls on a deleted object.
Each subclass of ArrayData needs a flag to track whether there's a strong iterator past the end of the array; use a spare bit in m_strongIterators to store the flag, and consolidate more strong iterator code in class ArrayData. This will also aid in packing fields in subclasses.
This was injected when I converted the strong iterator list to a linked list. Only affects HphpArray when COW occurs on the array being mutated in a mutable foreach loop. Starting a strong iteration causes a private copy to be made anyway, but the bug should be fixed either way.
The DebuggerClient destructor could try to invoke ~Array after the smart allocator shut down from a static dtor. In the case of the hphpd_get_client API, it also could try to assign null_array to an Array at sweep time---I think this could be wrong if these Array's have references to other Object's with custom sweeps.
Non-smart-allocated VectorArray wasn't initializing this field, which surely can't be good. This would most likely impact HPHPC but only when creating static arrays; and its not clear when/if we create static VectorArrays. But it's still a bug.
The getNoCheck function will assert that it's not null, which this code is apparently trying to check. (Somehow hit this loading a sandbox page, but not sure how to repro.)
file_put_contents' implementation was manually opening the passed in filename. If we use our File class instead, the magic php:// paths just work.
This could cause a local with a type assertion to be inferred non-null at places where thats not the case. In the new test, the $a in "return $a" was inferred to to be an object, resulting in a crash when $a was pushed onto the stack, and its refcount incremented.
Parallel query jobs dont need to do any of the normal thread initialization, so skip it.
I combed through HipHop's grammar and noticed a few bugs. HipHop's grammar does not allow for traits to be declared anywhere except toplevel scope (whereas Zend allows for this), and the grammar allows for bogus singleton XHP tags such as '<foo a="1" /foo>' (which are not allowed by the original XHP grammar given by xhpast). This diff fixes these bugs, and it also removes some superfluous rules, duplicated rules, and dead rules from the grammar. I also took a look at 14 shift/reduce conflicts in the grammar to see if I could eliminate most of them. 4 of the 14 conflicts went away when I fixed the issue with the xhp_tag_body rules and when I removed the dead type_decl rules. Of the 10 remaining conflicts, 2 were due to the if/else rules and the other 8 were due to the "expr -> expr [ dim_offset ]" rule. Conflicts due to "if/else" are well understood and conventional wisdom says we're better off just accepting these conflicts instead of contorting the grammar to try to get rid of them. Conflicts due to "expr -> expr [ dim_offset ]", however, are not really well understood and there are a lot of them, so it seemed worth fixing. "expr -> expr [ dim_offset ]" was originally added to the grammar to support using function calls as the base for array element expressions (ex. "$x = f()"). The rules for variable, calls, array elements, and object properties were written in a very weird way that made them hard to update, so I took the opportunity to rewrite these rules in a more natural form and I updated the rules to support using function calls as the base for array element expressions. Finally, I ran into cases where developers were using array literals, class constants, and parenthesized expressions as the base of array element expressions, so I introduced 'dim_expr' rules so that HipHop's grammar will continue to support these cases.
pcre_exec checks that its subject is valid utf8 every time it's called (unless told not to). Our preg_split implementation can end up calling pcre_exec once for every character in the subject for certain inputs, so rechecking the utf8 validity of the subject is a waste of cycles.
try/catch()/finally and try/finally constuctions added to hphp. Code is translated into C++. There still a lot to do: 1. Throw an exception when there's an unhandled exception in finally scope; 2. Write test units; 3. Support finally in virtual machine; 4. Return an error if there's a yield statement into try/finally scope.
This means we can avoid compiling with ENABLE_INTERCEPTS, which significantly reduces the size of the binary.
Converting to ThreadLocalSingleton means each MemoryManager instance is stored directly in __thread memory instead of malloc, and allows clients to directly access it via the x64 FS register. This avoids needing SmartAllocatorImpl::m_stats to update stats. Moved The GarbageList static_assert to memory_manager.cpp.
Failing to call this when there are live RequestLocal objects will can cause them to access deleted objects during pthread's shutdown (calling OnThreadExit). This fixes and adds assertions about ref counts that makes this easier to hit this in a debug build.
Some flib tests were failing, and the lines I looked at were for SetOpM. The bytecode.cpp version of these two uses MoreWarnings to decide whether warn is true for setHelper, so do something similar for the translator.
This is a wrapper around boost::numeric_cast, to give a helpful error message if we attempt to use an out of range immediate or jump in the assembler. I'm sure there are other places in the codebase it can be useful but this was the first that came to mind. In RELEASE=1 builds it's just a static_cast so there should be no runtime overhead.
The translations for the M* instructions call getMInstrCtx to set MInstrState::ctx if the context is not fixed, or if there are property accesses in the vector. But MInstrState::ctx is only read when the context is not fixed AND there are property accesses in the vector. Also found an issue where the BaseN* helpers would access the current frame without a VMRegAnchor. Fixed by passing in the correct fp as a parameter.
This checks to see whether a file could be included. For hhvm in sandbox mode, this just checks the existence of the file. For hhvm in RepoAuthoritative mode, it ignores the filesystem, and looks to see whether the file is in the repo. For hphpc it checks to see if the file was compiled into the binary.