Reviewers: dcarney, jarin,
Message:
PTAL.
Another chunk split off from the call IC removal CL.
Description:
Optimize HWrapReceiver
Please review this at https://codereview.chromium.org/135593006/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+42, -25 lines):
M src/hydrogen-instructions.h
M src/ia32/lithium-codegen-ia32.cc
M src/ia32/lithium-ia32.h
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
345c6b9a328820b27e27c1b6c4e03696d372a4f8..9d650fb4c949327e73559088bf768184a4278b72
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -3691,6 +3691,8 @@ class HWrapReceiver V8_FINAL : public
HTemplateInstruction<2> {
public:
DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
+ virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
+
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
@@ -3701,15 +3703,21 @@ class HWrapReceiver V8_FINAL : public
HTemplateInstruction<2> {
virtual HValue* Canonicalize() V8_OVERRIDE;
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
+ bool known_function() const { return known_function_; }
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
private:
HWrapReceiver(HValue* receiver, HValue* function) {
+ known_function_ = function->IsConstant() &&
+
HConstant::cast(function)->handle(function->isolate())->IsJSFunction();
set_representation(Representation::Tagged());
SetOperandAt(0, receiver);
SetOperandAt(1, function);
+ SetFlag(kUseGVN);
}
+
+ bool known_function_;
};
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
49e3da5639c6ad52037228c5c3130bcdcd0c8517..7e9cbc21c94a448b3c93f88445b7a8a707287c23
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3580,33 +3580,36 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength*
instr) {
void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
Register receiver = ToRegister(instr->receiver());
- Register function = ToRegister(instr->function());
- Register scratch = ToRegister(instr->temp());
// If the receiver is null or undefined, we have to pass the global
// object as a receiver to normal functions. Values have to be
// passed unchanged to builtins and strict-mode functions.
Label receiver_ok, global_object;
Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
+ Register scratch = ToRegister(instr->temp());
+
+ if (!instr->hydrogen()->known_function()) {
+ Register function = ToRegister(instr->function());
+
+ // Do not transform the receiver to object for strict mode
+ // functions.
+ __ mov(scratch,
+ FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
+ __ test_b(FieldOperand(scratch,
SharedFunctionInfo::kStrictModeByteOffset),
+ 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
+ __ j(not_equal, &receiver_ok, dist);
- // Do not transform the receiver to object for strict mode
- // functions.
- __ mov(scratch,
- FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
- __ test_b(FieldOperand(scratch,
SharedFunctionInfo::kStrictModeByteOffset),
- 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
- __ j(not_equal, &receiver_ok, dist);
-
- // Do not transform the receiver to object for builtins.
- __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
- 1 << SharedFunctionInfo::kNativeBitWithinByte);
- __ j(not_equal, &receiver_ok, dist);
-
- // Normal function. Replace undefined or null with global receiver.
- __ cmp(receiver, factory()->null_value());
- __ j(equal, &global_object, Label::kNear);
- __ cmp(receiver, factory()->undefined_value());
- __ j(equal, &global_object, Label::kNear);
+ // Do not transform the receiver to object for builtins.
+ __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
+ 1 << SharedFunctionInfo::kNativeBitWithinByte);
+ __ j(not_equal, &receiver_ok, dist);
+
+ // Normal function. Replace undefined or null with global receiver.
+ __ cmp(receiver, factory()->null_value());
+ __ j(equal, &global_object, Label::kNear);
+ __ cmp(receiver, factory()->undefined_value());
+ __ j(equal, &global_object, Label::kNear);
+ }
// The receiver should be a JS object.
__ test(receiver, Immediate(kSmiTagMask));
@@ -3615,11 +3618,16 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr)
{
DeoptimizeIf(below, instr->environment());
__ jmp(&receiver_ok, Label::kNear);
- __ bind(&global_object);
- __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
- __ mov(receiver,
- Operand(receiver,
Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- __ mov(receiver, FieldOperand(receiver,
GlobalObject::kGlobalReceiverOffset));
+ if (!instr->hydrogen()->known_function()) {
+ Register function = ToRegister(instr->function());
+
+ __ bind(&global_object);
+ __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
+ const int global_offset =
Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
+ __ mov(receiver, Operand(receiver, global_offset));
+ const int receiver_offset = GlobalObject::kGlobalReceiverOffset;
+ __ mov(receiver, FieldOperand(receiver, receiver_offset));
+ }
__ bind(&receiver_ok);
}
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index
8ec520321eca47183c2b59a0d8905fae32e26e60..811700a544aa9767d00b637930323a81c2a62794
100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -565,6 +565,7 @@ class LWrapReceiver V8_FINAL : public
LTemplateInstruction<1, 2, 1> {
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
+ DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
};
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.