We'd like to start using ##mixed## instead of ##var## for attribute types to be consistent with Hack. As a followup to this (once released), we would codemod all ##var## to ##mixed##.
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.
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.
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.
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.
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.
Instead of calling into the comparisons.h stuff, call into
the cell/tv functions. This meant moving more_or_equal and
less_or_equal to tv_comparisons and moving cellToBool out of its
unnamed namespace. Also replaces the global tv() function with some
make_tv() and make_value() thing---it looked like it was incorrect for
doubles, and since the correct compile-time type for the unconstrained
template parameter essentially depended on the runtime value of the
first parameter it seemed more reasonable to move that to
compile-time, too.
C++11 cleanup (clean up easy enums)
This is for runtime/base/... and ended up touching a lot of files
because it turns out we have a lot of reasonably behaved enums.
In repo mode this does the right thing and returns the right constant, but for non-repo it thinks it is an undefined non-namespace constant. I'll have to do something more hardcore if that starts to matter
While I was in there, I made the correct name for `ReflectionParameter` that was added in 5.4 instead of the draft we copied.
We were maintaining a flag that said if we were interpreting on the EC. It was only used in the implementation of hphp_break(), for pretty minimal benefit. I yanked it… it seems fine to me to throw the switch exception if someone steps out of the hard break even if we're already interpreting.
Also yank out a vestige of the previous stepping and breakpoint logic from the dispatch loop I noticed today. I'd previously missed it, but I made a change a while ago to put the state of the last location filter into the hands of the flow control commands. This was unnecessary and should have been removed then.
This was spewing on mediawiki and we need to update. It is backwards compat.
I tried to put the constants in PHP but failed. I spent 30 mins on it. I'll come back to it next time I get the itch.
Closes#812
If a function was called via (re)enterVM, and it didn't yet
have a prolog, and it was unable to get the write lease, and it was
intercepted, and the intercept handler asked for the original function
to be skipped, fcallHelper didn't return correctly, typically resulting
in the original function being re-executed, and then re-intercepted -
except that it was one level deeper in the vm-nesting hierarchy.
Eventually, it crashed.
Hopefully a little bit simpler, and duplicating less logic
with Stack::toString. Contains some fixes to visitStackElems to make
it work for this (it is printing some stacks slightly incorrectly
right now, too ... :)
Move all the stack unwinding code to its own module, delete
some redundant enumerations, document a few things. Gets rid of most
of the remnants of the old setjmp/longjmp-based implementation at the
enterVM level but doesn't do much to the unwinder itself (coming in
separate diff to hopefully be easier to review).
Remove unnecessary optimization that can be achieved in a more general
way and simplify continuation creation code.
VMExecutionContext::createContinuationHelper was renamed to
VMExecutionContext::createCont{Func,Meth}. The createContFunc no longer
takes this/class arguments, the createContMeth transfers them in one
Type::Ctx pointer that is used natively by ActRec's m_this. Since the
whole logic of this function is to set this single field, the logic is
now simpler.
Interpreter: iopCreateCont() just passes the m_this field of the parent
ActRec.
Translator: CreateCont opcode loads m_this field using LdCtx opcode.
This opcode optimizes into LdThis, which optimizes into
DefInlineFP->SpillFrame->object and allows frame to be eliminated, a
case previously covered by InlineCreateCont.
This diff uncovered a bug in trace builder, where LdCtx in static
methods could be optimized into LdThis, if the method was called thru
object. Fixed.
Save 8 bytes of m_args and its initialization for Continuations without
func_get_args() call (does not save real memory due to 16-byte alignment).
Store variable arguments in optional local.
Vector statements ending with a SetProp now properly free
memory when run with JIT enabled. Additionally, in both
JIT and interpreted mode memory will still be freed if
exceptions are thrown during evaluation of vector operations.
This is the first results from profiling callsites of
StringData::initLiteral. This diff converts a handful more
string literals to StaticString, removes overloaded Variant
comparison operators (operator==, etc), and avoids
constructing new strings in a few cases in tvCastToString
and tvCastToStringInPlace.
The codebase had several namespace-level static data definitions and function definitions. Using namespace-level "static" in a .h file is near-always a bad idea, as follows:
- for simple types, static is implied. Example: "const int x = 42;" is the same as "static const int x = 42;"
- for aggregate types, static linkage implies that a copy of the aggregate will appear in every compilation unit that includes the header.
- for functions, static means the function will have a separate body generated in each compilation unit including the header.
- in several places functions were defined 'static inline', which is just as bad. 'inline' is just a hint which means the function may end up having a body (and actually more due to 'static').
True, gnu's linker has means to remove duplicate definition, but that's not always guaranteed or possible (think e.g. static functions that define static data inside, ouch). So static is useless at best and pernicious at worst. We should never, ever use static at namespace level in headers. I will create a bootcamp task for a lint rule.
I expected the performance to be neutral after the change, but in fact there's a significant drop in instruction count and therefore a measurable reduction in CPU time: https://our.intern.facebook.com/intern/perflab/details.php?eq_id=431903
We had a lot of odd behavior with both Next and Out. Previously the debugger would interpret the world until it saw that it was no longer on a specific line, or at a specific stack depth. I changed it recently to let the program run normally, and use an internal breakpoint to control step outs. Next's become like a step out temporarily when you descend into a function and need to get back out to the original line, so some bugs with out showed as bugs with Next, too.
Specifically, any time more PHP code was executed as a "side-effect" of a non-fcall instruction, step out would get lost. In these cases the stack trace gives us the offset of the instruction causing the PHP to run, not the instruction that control will return to as is the case with a Fcall. A breakpoint set there would get missed. This changes the step out logic to recognize such cases (via the fact that a nested VM state was pushed to execute the code) and step out more intelligently. We look at the instruction in question, and determine where execution may go, which might be multiple places. I also made a small change to ensure that we don't stop in generated functions when stepping out, which cleans up the iterator experience quite a bit, and sets us up for proper generator stepping, which will come next.
This was barely a demonstrable win in sandbox mode when I first wrote
it and it's not even used in hhir. It's probably been bitrotting and is causing
crashes for some people. Time to say goodbye.
obsoletes D825704? populate our env array from environ,
then overlay local changes that were made to m_envs.
I didn't make this conditional on CLI but could if that is desirable.
I didn't tackle the allocate-after-fork issue that @jdelong raised in D825704
I'm committing my work on HphpArray in bite-sized pieces for easier review. This piece replaces calls to NEW with a factory method. There are many problems with operator new, starting with the fact that the allocator cannot communicate properly with the constructor.
The newly introduced factory method should return ArrayData but that causes many issues right now, so I left that step to a future diff.
I was learning from @jdelong and he said that you should use
double quotes for local includes and angle brackets for library
includes. I asked why our code was the way it was, and he said he wanted
to clean it up. I beat him to it :)
Conflicts:
hphp/runtime/base/server/admin_request_handler.cpp
hphp/runtime/vm/named_entity.h
It turned out a lot of the namespace stuff still worked. The biggest thing for the first pass is that we don't fallback to the global function or constant if there isn't a namespaced one.
Also, when a constant has a ##\## anywhere in it it throw an error when it isn't defined, instead of assuming the string.
This cleans up the code a lot, and takes it out of various hot
paths. It will impact perf for requests where intercepts are used,
but no longer penalizes requests that don't use intercepts.
Some head scratching until I realized that my `putenv()` calls
in my PHP script weren't actually changing the environment for subsequent
`proc_open()` calls.
What I'd like this diff to do (and I fully expect that I'm violating some
referencing rules in hhvm) is to fall back to using our current view of
the environment as maintained in the execution context in the case that
proc_open is not explicitly passed an environment array.
I think I've even added a test to prove that this works, but I haven't
read the manual and fbmake runtests takes too long, so I'm just going
ahead to submit this diff.
This improves both Next and Out to avoid interpreting and stepping everything between when they start and finish. Out now lets the program run free until a pseudo-breakpoint at the return site it hit. Next continues to single-step the source line being stepped over, but now lets the program run free under calls made from that line.
The logic in Next regarding "calls made from that line" is extremely generic. We don't look at, say, call opcodes and decide to do something special. Rather, when we find we're off the original source line and a frame deeper we setup a "step out" operation much like the Out command then let the program run free. When we reach our return point, we continue stepping like normal. This accounts for not just calls, but iterators, and anything else that causes more PHP to run under the original source line.
This change moves the flow control logic down in to the respective cmds: Next, Step, Out, Continue. These cmds get a crack at executing at various points in the interrupt/command processing path. These cmds now own setting up the last location filter, whether they need VM interrupts, and whether they're done or not.
We store a bunch of data into an ActRec on the stack, then
call a php-level function that calls a C++ function to copy it into an
ActRec on the heap. This should hopefully be a little better.
We can't box a non-ref value for a ref param because
we could be modifying an array with refCount != 1.
zend warns, skips the call and returns null. For now, this
makes us warn, but do the call (without modifying the array).
A file scope flag controls whether to skip the call or not,
and should be changed (and eliminated) once all our tests pass.
With the flag turned on, we still dont match zend's behavior,
because its happy to go ahead and call the function with no
warning in the case of a literal array parameter
(cuf('foo', array(1))), even though it warns and skips it when
the array is in a variable ($a=array(1); cuf('foo', $a)).
This is a partial step towards merging the HPHP::VM namespace
up into its parent. To keep it reviewable/mergeable I'm not doing
everything at once here, but most of the code I've touched seems
improved. I've drawn an invisible line around the jit, Unit and
its cohort (Class, Func, PreClass, etc.); we'll get back to them
soon.
Make the targetcache the one true home for constants,
so we dont need to (also) insert them all into
VMExecutionContext::m_constants (which is now gone).
By also making "non-volatile" constants persistent, we save
initializing most of them at all in RepoAuthoritative mode.