This function used memcpy on TypedValues where it doesn't
know the storage location, which is dangerous if the target lives in a
HphpArray (or anything else that uses m_aux). It also just seems like
it's now an unnecessary/redundant entry point in the typed value API.
Several uses of it are on things that can't be KindOfRef anyway (I
fixed constants, but where I wasn't sure I used tvToCell first).
This allows us to swap TypedValue.m_type and m_aux, which puts
m_type at offset 8 and simplifies the necessary code for passing
TypedValue by value. It also makes the m_type and m_data fields
of TypedValue contiguous.
Our request shutdown procedure cleared the autoload handler
before running destructors of any remaining objects. This was causing
fatals when some of those destructors tried to use a
class/function/constant that hadn't already been autoloaded.
And, several helper functions with the prefix "var" were changed
to the prefix "ref". I reworded the bytecode spec; the flavor letter
for PHP references is still 'V', but I reworded parts of it to use
the term 'pointer' instead of 'reference' in places where reference
was too overloaded. Renamed 'var' to 'ref' throughout.
Pulling the trigger; it's unused post-tx64. This diff preserves the
ability to mark units as merge-only when the pseudomain only contains
assignments to known globals. When the unit is being merged, the set
operation goes directly to the global varenv instead of through the
targetcache (GlobalCache stored pointers into the global varenv's
NameValueTable).
Supersedes D891179 -- I was overly aggressive in that one.
Most of the values stored in TypedValue in ext_asio are always Cells.
Let's use Cell type alias to improve code readability, pass them by
reference where null is not allowed and use Cell-specific functions
from tv_helpers.h.
No emitted bytecode relies on Continuation being stored in local 0
anymore. Stop using local 0 for this purpose and compute offset
to the Continuation at JIT time. 16 bytes of memory freed.
At this point all locals of Continuation construction wrapper share the
same indices with their respective locals of Continuation body, which
should allow further optimizations.
This is an incremental step towards moving it all the way
to hphp/server. This flattens base but doesn't untangle
the server files from lib_hphp_runtime
Fix a long-standing bug where if you step off of the end of pseudo main we'd segfault in the interpreter loop. To get this we have to have a breakpoint in the final TC in pseudo main, and have that called from another TC, then Step or Next off the end. We'd end up with a PC of zero after the ret, which makes sense, but the logic after interpreting a block of code to stay in the interpreter when debugging was blind to this case.
For PhpFiles, there was a mixed management system, where references from
translated code were held until the code was made unreachable, while
references from interpreted code were held for the duration of the
current request. Under the new scheme, PhpFiles are always treadmilled.
They are owned by the FileRepository, and so need to be ref-counted
because the FileRepository can have the same PhpFile under multiple
paths. But we don't ref-count the *uses* of PhpFiles anymore.
Classes still need to be ref-counted, but as soon as their Unit
goes away, most of their internals can be freed. We just need to
hold onto them if derived classes are referencing them. Even in
that case, the next time we try to instantiate the derived class,
we can kill any that reference this Class.
There were also lots of holes where references were not dropped,
or owned data structures were not destroyed. eg a Class's methods
were not destroyed when the Class was destroyed; there were
several paths where an entry was erased from the file map, but the
corresponding PhpFile was not decRef'd - or worse, a null entry
was left in the map (something we had asserts to check for).
This tries to make the handling more consistent.
When object support was first added to HHVM, a class named "Instance"
was introduced (deriving from ObjectData) to represent instances of user
defined classes. Since then, things have evolved and HPHPc and HPHPi have
been retired, and now there really is no needed to have ObjectData and
Instance be separate classes anymore.
This diff moves all of the functionality from the Instance class to the
ObjectData and removes the Instance class. In the process, I got rid of
a bunch of dead methods and fixed some indentation and other style issues.
Added IR opcodes to perform MIter* instructions in JIT. Added IterBreakV bytecode
operation to break out of multiple loops containing iterators. Emitter and assembler
were modified to support such use.
If we're not going to mutate the Cell, it might make sense to
pass it by value rather than pointer to const. Do folks like this
better? I can see a couple arguments various ways. But it does seem
like even if we want to pass it by pointer at the hardware level we
would ideally passing by const reference at the language level, so
this choice would be transparent at callsite code. This diff doesn't
change anything in tv_helpers.h for now.
Adds an extension command to the debugger which provides
heap tracing functionality, and adds the framework needed to get
heap traces. The heaptrace command can dump the current heap to the
debugger session or it can save a GraphViz specification to a file.
I'm hoping to add a backend which can put the graph in GML format,
so it can be explored interactively. I also hope at some point to
see this integrated into FBIDE if we can do that.
Turns out I need to use tvSet with temporaries. Also removes
unused tvSetObject*, and replaces some tvSetNull* callsites with using
make_tv temporaries.
Deletes operator overloads on variant for the same and points
bytecode.cpp at them. Also fixes one known accidental deviation from
zend. These functions take Cells by value because it seemed to make
sense---I'll likely convert the various functions in the new
tv_conversions.h (and tv_comparisons.h) to do the same but in another
diff.
Since TypedValue::operator= is dangerous, something like
tvTeleport is usually what you want to use, but it doesn't work with
temporary TypedValues (e.g. return values of things like make_tv or
cellAdd), because it took the arguments by pointer. This also means
we can change it to take parameters by value later without updating
callsites. This diff does the tvDup family and changes tvTeleport to
tvCopy. I'll gradually get the other ones done, but I just need these
for now to work with temporaries for changing SetOp to not use Variant
arithmetic.
Updates continuations to allow yielding of a key-value
pair from a generator. Adds bytecode instructions (PackContK,
ContKey) for using the new feature, and adds IR instructions
(ContUpdateIdx, ContIncKey) to help get it down to the metal
(in particular, ContIncKey attempts to keep the current use-cases
as fast as possible).
A recent diff called my attention to the logic in enterDebuggerDummyEnv()
and exitDebuggerDummyEnv() and I noticed it didn't look quite right.
The first time enterDebuggerDummyEnv() is called it creates a frame on an
empty call stack, but then exitDebuggerDummyEnv() does not correctly tear
down this frame and null out m_fp and m_pc, and this leads to subtle issues.
For example, invokeFunc() checks if m_fp is null to decide whether to call
enterVM() or reenterVM(). I found a case with the "flow_gen_excep.php" test
where invokeFunc was incorrectly calling reenterVM (because m_fp hadn't
been nulled out) and it was pushing bogus VM state info into m_nestedVMs.
This in turn was causing the logic in CmdNext::onBeginInterrupt() to get
confused when comparing the original stack depth with the current stack
depth.
This diff updates exitDebuggerDummyEnv() to correctly tear down the frame
and null out m_fp and m_pc, and it updates enterDebuggerDummyEnv() to
assume the callstack is always empty (which should be the case). I've also
beefed up the asserts in both of these methods.
PackCont opcode is always followed by ContExit so let's join them into ContSuspend. ContResume counterpart may come later (replacing ContNext/Send/Raise/Enter).
Fix a cast from a previous diff, and fix surprise checks that throw
exceptions. I turned the two macros into functions to clean things up; the
important part of the fix is taking out the SYNC() before
EventHook::CheckSurprise(). Before this fix, the saved offset in the ActRec
used for reentry would point at the offset immediate of the Jmp instead of the
Jmp itself.
Continuation's m_received field is used to transfer values and
exceptions to the Continuation by send() and raise() methods. It has a
valid value only for a short duration of time, between
ContNext/ContSend/ContRaise and UnpackCont opcodes, when no other
operations could possibly occur. Let's free these 16 bytes of memory and
pass the value thru the VM stack.
To achieve this goal, ContEnter was modified to accept a value to be
transferred on the stack. The existence of the value on the stack is
then acknowledged by the UnpackCont opcode, which is the first opcode
executed after ContEnter enters the continuation body.
ContNext then becomes a trivial Null and is thus removed, ContSend just
teleports the value from local 0 to the stack (I will experiment in a
follow up diff with replacing ContSent by CGetL+UnsetL). ContRaise has
to update the label, but the eventual plan is to enter into unwinder
directly from the raise() method.
Continuaton::send()/raise() are holding reference to the sent value
while the next iteration is being executed. Do not hold this reference
and teleport values instead.
Add ContCheck opcode that moves away responsibility of checking
Continuation status from Cont{Next,Send,Raise} opcodes.
This check needs to run outside of try/catch in next()/send()/raise()
methods and moving it to a separate opcode lets us merge
Cont{Next,Send,Raise} with ContEnter.
Apparently VarEnv's m_previous is not used for anything. Let's kill its
maintenance and avoid 2 native calls per Continuation
next()/send()/raise() calls.
Because stronger types are better types, and this will make
future refactoring easier. I considered trying to purge the Opcode
type from the codebase too but that would be a much bigger project.
Adds support for checking ?Foo type hints in VerifyParamType.
The parameter must have type Foo or null. Failing to pass the hint is
reported as a warning instead of a recoverable error for now for
migration reasons---we'll want to convert it to be the same as normal
type hints later.