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) { ...@@ -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) { void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope; VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 0); ASSERT(args->length() == 0);
......
...@@ -333,6 +333,9 @@ class CodeGenerator: public AstVisitor { ...@@ -333,6 +333,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args); void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args); void GenerateArgumentsAccess(ZoneList<Expression*>* args);
......
...@@ -416,6 +416,7 @@ CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = { ...@@ -416,6 +416,7 @@ CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
{&CodeGenerator::GenerateIsSmi, "_IsSmi"}, {&CodeGenerator::GenerateIsSmi, "_IsSmi"},
{&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"}, {&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"},
{&CodeGenerator::GenerateIsArray, "_IsArray"}, {&CodeGenerator::GenerateIsArray, "_IsArray"},
{&CodeGenerator::GenerateIsConstructCall, "_IsConstructCall"},
{&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"}, {&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"},
{&CodeGenerator::GenerateArgumentsAccess, "_Arguments"}, {&CodeGenerator::GenerateArgumentsAccess, "_Arguments"},
{&CodeGenerator::GenerateValueOf, "_ValueOf"}, {&CodeGenerator::GenerateValueOf, "_ValueOf"},
......
...@@ -424,7 +424,7 @@ function TimeClip(time) { ...@@ -424,7 +424,7 @@ function TimeClip(time) {
%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) { %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
if (%IsConstructCall()) { if (%_IsConstructCall()) {
// ECMA 262 - 15.9.3 // ECMA 262 - 15.9.3
var argc = %_ArgumentsLength(); var argc = %_ArgumentsLength();
if (argc == 0) { if (argc == 0) {
......
...@@ -4987,6 +4987,29 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { ...@@ -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) { void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0); ASSERT(args->length() == 0);
// ArgumentsAccessStub takes the parameter count as an input argument // ArgumentsAccessStub takes the parameter count as an input argument
......
...@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor { ...@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args); void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args); void GenerateArgumentsAccess(ZoneList<Expression*>* args);
......
...@@ -659,7 +659,7 @@ function DefineError(f) { ...@@ -659,7 +659,7 @@ function DefineError(f) {
%SetProperty(f.prototype, 'constructor', f, DONT_ENUM); %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
f.prototype.name = name; f.prototype.name = name;
%SetCode(f, function(m) { %SetCode(f, function(m) {
if (%IsConstructCall()) { if (%_IsConstructCall()) {
if (m === kAddMessageAccessorsMarker) { if (m === kAddMessageAccessorsMarker) {
DefineOneShotAccessor(this, 'message', function (obj) { DefineOneShotAccessor(this, 'message', function (obj) {
return FormatMessage({type: obj.type, args: obj.arguments}); return FormatMessage({type: obj.type, args: obj.arguments});
......
...@@ -103,7 +103,7 @@ function DoConstructRegExp(object, pattern, flags, isConstructorCall) { ...@@ -103,7 +103,7 @@ function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
function RegExpConstructor(pattern, flags) { function RegExpConstructor(pattern, flags) {
if (%IsConstructCall()) { if (%_IsConstructCall()) {
DoConstructRegExp(this, pattern, flags, true); DoConstructRegExp(this, pattern, flags, true);
} else { } else {
// RegExp : Called as function; see ECMA-262, section 15.10.3.1. // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
// Set the String function and constructor. // Set the String function and constructor.
%SetCode($String, function(x) { %SetCode($String, function(x) {
var value = %_ArgumentsLength() == 0 ? '' : ToString(x); var value = %_ArgumentsLength() == 0 ? '' : ToString(x);
if (%IsConstructCall()) { if (%_IsConstructCall()) {
%_SetValueOf(this, value); %_SetValueOf(this, value);
} else { } else {
return value; return value;
......
...@@ -154,7 +154,7 @@ function SetupGlobal() { ...@@ -154,7 +154,7 @@ function SetupGlobal() {
// ECMA-262 - 15.1.1.3. // ECMA-262 - 15.1.1.3.
%SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE); %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
// Setup non-enumerable function on the global object. // Setup non-enumerable function on the global object.
InstallFunctions(global, DONT_ENUM, $Array( InstallFunctions(global, DONT_ENUM, $Array(
"isNaN", GlobalIsNaN, "isNaN", GlobalIsNaN,
...@@ -174,7 +174,7 @@ SetupGlobal(); ...@@ -174,7 +174,7 @@ SetupGlobal();
%SetCode($Boolean, function(x) { %SetCode($Boolean, function(x) {
if (%IsConstructCall()) { if (%_IsConstructCall()) {
%_SetValueOf(this, ToBoolean(x)); %_SetValueOf(this, ToBoolean(x));
} else { } else {
return ToBoolean(x); return ToBoolean(x);
...@@ -273,7 +273,7 @@ function ObjectLookupSetter(name) { ...@@ -273,7 +273,7 @@ function ObjectLookupSetter(name) {
%SetCode($Object, function(x) { %SetCode($Object, function(x) {
if (%IsConstructCall()) { if (%_IsConstructCall()) {
if (x == null) return this; if (x == null) return this;
return ToObject(x); return ToObject(x);
} else { } else {
...@@ -350,7 +350,7 @@ SetupBoolean(); ...@@ -350,7 +350,7 @@ SetupBoolean();
// Set the Number function and constructor. // Set the Number function and constructor.
%SetCode($Number, function(x) { %SetCode($Number, function(x) {
var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x); var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
if (%IsConstructCall()) { if (%_IsConstructCall()) {
%_SetValueOf(this, value); %_SetValueOf(this, value);
} else { } else {
return value; return value;
...@@ -570,4 +570,3 @@ function SetupFunction() { ...@@ -570,4 +570,3 @@ function SetupFunction() {
} }
SetupFunction(); SetupFunction();
...@@ -3330,6 +3330,14 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { ...@@ -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) { void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0); ASSERT(args->length() == 0);
// ArgumentsAccessStub takes the parameter count as an input argument // ArgumentsAccessStub takes the parameter count as an input argument
......
...@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor { ...@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
void GenerateIsArray(ZoneList<Expression*>* args); void GenerateIsArray(ZoneList<Expression*>* args);
// Support for construct call checks.
void GenerateIsConstructCall(ZoneList<Expression*>* args);
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(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