| Index: src/ia32/codegen-ia32.h
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.h (revision 4205)
|
| +++ src/ia32/codegen-ia32.h (working copy)
|
| @@ -339,6 +339,10 @@
|
| bool in_spilled_code() const { return in_spilled_code_; }
|
| void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
|
|
|
| + // If the name is an inline runtime function call return the number of
|
| + // expected arguments. Otherwise return -1.
|
| + static int InlineRuntimeCallArgumentsCount(Handle<String> name);
|
| +
|
| private:
|
| // Construction/Destruction
|
| explicit CodeGenerator(MacroAssembler* masm);
|
| @@ -353,6 +357,23 @@
|
| // State
|
| ControlDestination* destination() const { return state_->destination(); }
|
|
|
| + // Control of side-effect-free int32 expression compilation.
|
| + bool in_safe_int32_mode() { return in_safe_int32_mode_; }
|
| + void set_in_safe_int32_mode(bool value) { in_safe_int32_mode_ = value; }
|
| + bool safe_int32_mode_enabled() {
|
| + return FLAG_safe_int32_compiler && safe_int32_mode_enabled_;
|
| + }
|
| + void set_safe_int32_mode_enabled(bool value) {
|
| + safe_int32_mode_enabled_ = value;
|
| + }
|
| + void set_unsafe_bailout(BreakTarget* unsafe_bailout) {
|
| + unsafe_bailout_ = unsafe_bailout;
|
| + }
|
| +
|
| + // Take the Result that is an untagged int32, and convert it to a tagged
|
| + // Smi or HeapNumber. Remove the untagged_int32 flag from the result.
|
| + void ConvertInt32ResultToNumber(Result* value);
|
| +
|
| // Track loop nesting level.
|
| int loop_nesting() const { return loop_nesting_; }
|
| void IncrementLoopNesting() { loop_nesting_++; }
|
| @@ -409,7 +430,7 @@
|
| return ContextOperand(esi, Context::GLOBAL_INDEX);
|
| }
|
|
|
| - void LoadCondition(Expression* x,
|
| + void LoadCondition(Expression* expr,
|
| ControlDestination* destination,
|
| bool force_control);
|
| void Load(Expression* expr);
|
| @@ -421,6 +442,11 @@
|
| // temporarily while the code generator is being transformed.
|
| void LoadAndSpill(Expression* expression);
|
|
|
| + // Evaluate an expression and place its value on top of the frame,
|
| + // using, or not using, the side-effect-free expression compiler.
|
| + void LoadInSafeInt32Mode(Expression* expr, BreakTarget* unsafe_bailout);
|
| + void LoadWithSafeInt32ModeDisabled(Expression* expr);
|
| +
|
| // Read a value from a slot and leave it on top of the expression stack.
|
| Result LoadFromSlot(Slot* slot, TypeofState typeof_state);
|
| Result LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state);
|
| @@ -465,7 +491,8 @@
|
| void GenericBinaryOperation(
|
| Token::Value op,
|
| StaticType* type,
|
| - OverwriteMode overwrite_mode);
|
| + OverwriteMode overwrite_mode,
|
| + bool no_negative_zero);
|
|
|
| // If possible, combine two constant smi values using op to produce
|
| // a smi result, and push it on the virtual frame, all at compile time.
|
| @@ -473,22 +500,30 @@
|
| bool FoldConstantSmis(Token::Value op, int left, int right);
|
|
|
| // Emit code to perform a binary operation on a constant
|
| - // smi and a likely smi. Consumes the Result *operand.
|
| + // smi and a likely smi. Consumes the Result operand.
|
| Result ConstantSmiBinaryOperation(Token::Value op,
|
| Result* operand,
|
| Handle<Object> constant_operand,
|
| StaticType* type,
|
| bool reversed,
|
| - OverwriteMode overwrite_mode);
|
| + OverwriteMode overwrite_mode,
|
| + bool no_negative_zero);
|
|
|
| // Emit code to perform a binary operation on two likely smis.
|
| // The code to handle smi arguments is produced inline.
|
| - // Consumes the Results *left and *right.
|
| + // Consumes the Results left and right.
|
| Result LikelySmiBinaryOperation(Token::Value op,
|
| Result* left,
|
| Result* right,
|
| - OverwriteMode overwrite_mode);
|
| + OverwriteMode overwrite_mode,
|
| + bool no_negative_zero);
|
|
|
| +
|
| + // Emit code to perform a binary operation on two untagged int32 values.
|
| + // The values are on top of the frame, and the result is pushed on the frame.
|
| + void Int32BinaryOperation(BinaryOperation* node);
|
| +
|
| +
|
| void Comparison(AstNode* node,
|
| Condition cc,
|
| bool strict,
|
| @@ -522,6 +557,7 @@
|
| struct InlineRuntimeLUT {
|
| void (CodeGenerator::*method)(ZoneList<Expression*>*);
|
| const char* name;
|
| + int nargs;
|
| };
|
|
|
| static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
|
| @@ -555,7 +591,7 @@
|
|
|
| // Support for arguments.length and arguments[?].
|
| void GenerateArgumentsLength(ZoneList<Expression*>* args);
|
| - void GenerateArgumentsAccess(ZoneList<Expression*>* args);
|
| + void GenerateArguments(ZoneList<Expression*>* args);
|
|
|
| // Support for accessing the class and value fields of an object.
|
| void GenerateClassOf(ZoneList<Expression*>* args);
|
| @@ -593,14 +629,10 @@
|
| // Fast support for number to string.
|
| void GenerateNumberToString(ZoneList<Expression*>* args);
|
|
|
| - // Fast support for Math.pow().
|
| + // Fast call to math functions.
|
| void GenerateMathPow(ZoneList<Expression*>* args);
|
| -
|
| - // Fast call to transcendental functions.
|
| void GenerateMathSin(ZoneList<Expression*>* args);
|
| void GenerateMathCos(ZoneList<Expression*>* args);
|
| -
|
| - // Fast case for sqrt
|
| void GenerateMathSqrt(ZoneList<Expression*>* args);
|
|
|
| // Simple condition analysis.
|
| @@ -620,6 +652,8 @@
|
| void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
|
| void CodeForSourcePosition(int pos);
|
|
|
| + void SetTypeForStackSlot(Slot* slot, NumberInfo info);
|
| +
|
| #ifdef DEBUG
|
| // True if the registers are valid for entry to a block. There should
|
| // be no frame-external references to (non-reserved) registers.
|
| @@ -638,10 +672,14 @@
|
| RegisterAllocator* allocator_;
|
| CodeGenState* state_;
|
| int loop_nesting_;
|
| + bool in_safe_int32_mode_;
|
| + bool safe_int32_mode_enabled_;
|
|
|
| // Jump targets.
|
| // The target of the return from the function.
|
| BreakTarget function_return_;
|
| + // The target of the bailout from a side-effect-free int32 subexpression.
|
| + BreakTarget* unsafe_bailout_;
|
|
|
| // True if the function return is shadowed (ie, jumping to the target
|
| // function_return_ does not jump to the true function return, but rather
|
| @@ -976,6 +1014,42 @@
|
| };
|
|
|
|
|
| +class RecordWriteStub : public CodeStub {
|
| + public:
|
| + RecordWriteStub(Register object, Register addr, Register scratch)
|
| + : object_(object), addr_(addr), scratch_(scratch) { }
|
| +
|
| + void Generate(MacroAssembler* masm);
|
| +
|
| + private:
|
| + Register object_;
|
| + Register addr_;
|
| + Register scratch_;
|
| +
|
| +#ifdef DEBUG
|
| + void Print() {
|
| + PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n",
|
| + object_.code(), addr_.code(), scratch_.code());
|
| + }
|
| +#endif
|
| +
|
| + // Minor key encoding in 12 bits of three registers (object, address and
|
| + // scratch) OOOOAAAASSSS.
|
| + class ScratchBits: public BitField<uint32_t, 0, 4> {};
|
| + class AddressBits: public BitField<uint32_t, 4, 4> {};
|
| + class ObjectBits: public BitField<uint32_t, 8, 4> {};
|
| +
|
| + Major MajorKey() { return RecordWrite; }
|
| +
|
| + int MinorKey() {
|
| + // Encode the registers.
|
| + return ObjectBits::encode(object_.code()) |
|
| + AddressBits::encode(addr_.code()) |
|
| + ScratchBits::encode(scratch_.code());
|
| + }
|
| +};
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|
| #endif // V8_IA32_CODEGEN_IA32_H_
|
|
|