Commit a1622491 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Optimize %IsConstructCall() on IA-32.

Review URL: http://codereview.chromium.org/150018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2290 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 14d126d3
......@@ -3290,6 +3290,14 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 0);
frame_->CallRuntime(Runtime::kIsConstructCall, 0);
frame_->EmitPush(r0);
}
void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 0);
......
......@@ -333,6 +333,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args);
......
......@@ -416,6 +416,7 @@ CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
{&CodeGenerator::GenerateIsSmi, "_IsSmi"},
{&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"},
{&CodeGenerator::GenerateIsArray, "_IsArray"},
{&CodeGenerator::GenerateIsConstructCall, "_IsConstructCall"},
{&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"},
{&CodeGenerator::GenerateArgumentsAccess, "_Arguments"},
{&CodeGenerator::GenerateValueOf, "_ValueOf"},
......
......@@ -424,7 +424,7 @@ function TimeClip(time) {
%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
// ECMA 262 - 15.9.3
var argc = %_ArgumentsLength();
if (argc == 0) {
......
......@@ -4987,6 +4987,29 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0);
// Get the frame pointer for the calling frame.
Result fp = allocator()->Allocate();
__ mov(fp.reg(), Operand(ebp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
Label check_frame_marker;
__ cmp(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
Immediate(ArgumentsAdaptorFrame::SENTINEL));
__ j(not_equal, &check_frame_marker);
__ mov(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
__ bind(&check_frame_marker);
__ cmp(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
fp.Unuse();
destination()->Split(equal);
}
void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0);
// ArgumentsAccessStub takes the parameter count as an input argument
......
......@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args);
......
......@@ -659,7 +659,7 @@ function DefineError(f) {
%SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
f.prototype.name = name;
%SetCode(f, function(m) {
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
if (m === kAddMessageAccessorsMarker) {
DefineOneShotAccessor(this, 'message', function (obj) {
return FormatMessage({type: obj.type, args: obj.arguments});
......
......@@ -103,7 +103,7 @@ function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
function RegExpConstructor(pattern, flags) {
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
DoConstructRegExp(this, pattern, flags, true);
} else {
// RegExp : Called as function; see ECMA-262, section 15.10.3.1.
......
......@@ -35,7 +35,7 @@
// Set the String function and constructor.
%SetCode($String, function(x) {
var value = %_ArgumentsLength() == 0 ? '' : ToString(x);
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
%_SetValueOf(this, value);
} else {
return value;
......
......@@ -154,7 +154,7 @@ function SetupGlobal() {
// ECMA-262 - 15.1.1.3.
%SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
// Setup non-enumerable function on the global object.
InstallFunctions(global, DONT_ENUM, $Array(
"isNaN", GlobalIsNaN,
......@@ -174,7 +174,7 @@ SetupGlobal();
%SetCode($Boolean, function(x) {
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
%_SetValueOf(this, ToBoolean(x));
} else {
return ToBoolean(x);
......@@ -273,7 +273,7 @@ function ObjectLookupSetter(name) {
%SetCode($Object, function(x) {
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
if (x == null) return this;
return ToObject(x);
} else {
......@@ -350,7 +350,7 @@ SetupBoolean();
// Set the Number function and constructor.
%SetCode($Number, function(x) {
var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
if (%IsConstructCall()) {
if (%_IsConstructCall()) {
%_SetValueOf(this, value);
} else {
return value;
......@@ -570,4 +570,3 @@ function SetupFunction() {
}
SetupFunction();
......@@ -3330,6 +3330,14 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
// TODO(X64): Optimize this like it's done on IA-32.
ASSERT(args->length() == 0);
Result answer = frame_->CallRuntime(Runtime::kIsConstructCall, 0);
frame_->Push(&answer);
}
void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0);
// ArgumentsAccessStub takes the parameter count as an input argument
......
......@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment