Revision: 10384
Author: [email protected]
Date: Wed Jan 11 02:35:37 2012
Log: Support inlining and crankshaft optimization of Math.random.
[email protected]
BUG=
TEST=
Review URL: http://codereview.chromium.org/9167011
http://code.google.com/p/v8/source/detail?r=10384
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Jan 11 00:29:42 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Jan 11 02:35:37 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1425,6 +1425,15 @@
instr,
CAN_DEOPTIMIZE_EAGERLY);
}
+
+
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+ LOperand* global_object = UseFixed(instr->global_object(), r0);
+ LRandom* result = new LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, d7), instr);
+}
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Dec 20 02:57:12 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Jan 11 02:35:37 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -141,6 +141,7 @@
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(ShiftI) \
@@ -1026,6 +1027,17 @@
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jan 11
01:39:37 2012
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jan 11
02:35:37 2012
@@ -3193,6 +3193,30 @@
__ CallStub(&stub);
}
}
+
+
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(d7));
+ ASSERT(ToRegister(instr->InputAt(0)).is(r0));
+
+ __ PrepareCallCFunction(1, scratch0());
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()),
1);
+
+ // 0x41300000 is the top half of 1.0 x 2^20 as a double.
+ // Create this constant using mov/orr to avoid PC relative load.
+ __ mov(r1, Operand(0x41000000));
+ __ orr(r1, r1, Operand(0x300000));
+ // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
+ __ vmov(d7, r0, r1);
+ // Move 0x4130000000000000 to VFP.
+ __ mov(r0, Operand(0, RelocInfo::NONE));
+ __ vmov(d8, r0, r1);
+ // Subtract and store the result in the heap number.
+ __ vsub(d7, d7, d8);
+}
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Jan 11 02:01:59
2012
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Jan 11 02:35:37
2012
@@ -146,6 +146,7 @@
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(Sar) \
@@ -2998,6 +2999,23 @@
};
+class HRandom: public HTemplateInstruction<1> {
+ public:
+ explicit HRandom(HValue* global_object) {
+ SetOperandAt(0, global_object);
+ set_representation(Representation::Double());
+ }
+
+ HValue* global_object() { return OperandAt(0); }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random)
+};
+
+
class HAdd: public HArithmeticBinaryOperation {
public:
HAdd(HValue* context, HValue* left, HValue* right)
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Jan 9 08:37:47 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Jan 11 02:35:37 2012
@@ -5127,6 +5127,18 @@
ast_context()->ReturnInstruction(result, expr->id());
return true;
}
+ break;
+ case kMathRandom:
+ if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
+ AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ Drop(1);
+ HValue* context = environment()->LookupContext();
+ HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ AddInstruction(global_object);
+ HRandom* result = new(zone()) HRandom(global_object);
+ ast_context()->ReturnInstruction(result, expr->id());
+ return true;
+ }
break;
default:
// Not yet supported for inlining.
@@ -6575,7 +6587,11 @@
// Fast support for Math.random().
void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
- return Bailout("inlined runtime function: RandomHeapNumber");
+ HValue* context = environment()->LookupContext();
+ HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ AddInstruction(global_object);
+ HRandom* result = new(zone()) HRandom(global_object);
+ return ast_context()->ReturnInstruction(result, call->id());
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jan 11
01:39:37 2012
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jan 11
02:35:37 2012
@@ -3012,6 +3012,29 @@
__ CallStub(&stub);
}
}
+
+
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+
+ __ PrepareCallCFunction(1, ebx);
+ __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
+ __ mov(Operand(esp, 0), eax);
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()),
1);
+
+ // Convert 32 random bits in eax to 0.(32 random bits) in a double
+ // by computing:
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
+ __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
+ __ movd(xmm2, ebx);
+ __ movd(xmm1, eax);
+ __ cvtss2sd(xmm2, xmm2);
+ __ xorps(xmm1, xmm2);
+ __ subsd(xmm1, xmm2);
+}
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Jan 11 00:29:42
2012
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Jan 11 02:35:37
2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1467,6 +1467,15 @@
return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
CAN_DEOPTIMIZE_EAGERLY);
}
+
+
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+ LOperand* global_object = UseFixed(instr->global_object(), eax);
+ LRandom* result = new(zone()) LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+}
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Dec 20 02:57:12 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Jan 11 02:35:37 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -135,6 +135,7 @@
V(OuterContext) \
V(Parameter) \
V(Power) \
+ V(Random) \
V(PushArgument) \
V(RegExpLiteral) \
V(Return) \
@@ -1043,6 +1044,17 @@
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Jan 10 08:11:33 2012
+++ /branches/bleeding_edge/src/objects.h Wed Jan 11 02:35:37 2012
@@ -4893,7 +4893,8 @@
V(Math, atan, MathATan) \
V(Math, exp, MathExp) \
V(Math, sqrt, MathSqrt) \
- V(Math, pow, MathPow)
+ V(Math, pow, MathPow) \
+ V(Math, random, MathRandom)
enum BuiltinFunctionId {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jan 11
01:39:37 2012
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jan 11
02:35:37 2012
@@ -2929,6 +2929,38 @@
__ CallStub(&stub);
}
}
+
+
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+
+ // Choose the right register for the first argument depending on
+ // calling convention.
+#ifdef _WIN64
+ ASSERT(ToRegister(instr->InputAt(0)).is(rcx));
+ Register global_object = rcx;
+#else
+ ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
+ Register global_object = rdi;
+#endif
+
+ __ PrepareCallCFunction(1);
+ __ movq(global_object,
+ FieldOperand(global_object, GlobalObject::kGlobalContextOffset));
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()),
1);
+
+ // Convert 32 random bits in rax to 0.(32 random bits) in a double
+ // by computing:
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
+ __ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
+ __ movd(xmm2, rcx);
+ __ movd(xmm1, rax);
+ __ cvtss2sd(xmm2, xmm2);
+ __ xorps(xmm1, xmm2);
+ __ subsd(xmm1, xmm2);
+}
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Jan 11 00:29:42 2012
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Jan 11 02:35:37 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1413,6 +1413,19 @@
return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
CAN_DEOPTIMIZE_EAGERLY);
}
+
+
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+#ifdef _WIN64
+ LOperand* global_object = UseFixed(instr->global_object(), rcx);
+#else
+ LOperand* global_object = UseFixed(instr->global_object(), rdi);
+#endif
+ LRandom* result = new LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+}
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Dec 20 02:57:12 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Jan 11 02:35:37 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -141,6 +141,7 @@
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(ShiftI) \
@@ -1024,6 +1025,17 @@
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev