| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 016d768958b2eee454036029faa4be30290ba9b7..825c4372f5a7084adf4db476a06feb2f477825de 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -6635,6 +6635,77 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
|
| }
|
|
|
|
|
| +bool HOptimizedGraphBuilder::TryMathConstant(Property* expr) {
|
| + // Should be either .PI or ["PI"] etc
|
| + if (!expr->key()->IsPropertyName()) return false;
|
| + // Must refer to a variable called "Math" that is a global variable
|
| + VariableProxy* proxy = expr->obj()->AsVariableProxy();
|
| + if (proxy == NULL) return false;
|
| + if (!proxy->var()->IsUnallocated()) return false;
|
| + if (!(proxy->var()->name()->IsOneByteEqualTo(
|
| + STATIC_ASCII_VECTOR("Math")))) return false;
|
| + // The global Math property must still be
|
| + // pointing to the instance of MathConstructor object
|
| + if (!current_info()->has_global_object() ||
|
| + current_info()->global_object()->IsAccessCheckNeeded()) {
|
| + return false;
|
| + }
|
| + Handle<GlobalObject> global(current_info()->global_object());
|
| + LookupResult lookup(isolate());
|
| + global->Lookup(*proxy->var()->name(), &lookup);
|
| +
|
| + if (!lookup.IsNormal() || !lookup.GetValue()->IsJSObject()) {
|
| + return false;
|
| + }
|
| +
|
| + Handle<JSObject> mathObject(JSObject::cast(lookup.GetValue()));
|
| +
|
| + if (!mathObject->map()->constructor()->IsJSFunction()) {
|
| + return false;
|
| + }
|
| +
|
| + Handle<JSFunction> constructor(
|
| + JSFunction::cast(mathObject->map()->constructor()));
|
| +
|
| + // Users cannot set instance_class_name so this can be trusted
|
| + Handle<String> instance_name(
|
| + String::cast(constructor->shared()->instance_class_name()));
|
| + if (!instance_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Math"))) {
|
| + return false;
|
| + }
|
| +
|
| + Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
|
| + HConstant* constant = NULL;
|
| +
|
| + if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("SQRT2"))) {
|
| + constant = New<HConstant>(1.4142135623730951);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("E"))) {
|
| + constant = New<HConstant>(2.718281828459045);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("LN2"))) {
|
| + constant = New<HConstant>(0.6931471805599453);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("LN10"))) {
|
| + constant = New<HConstant>(2.302585092994046);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("LOG2E"))) {
|
| + constant = New<HConstant>(1.4426950408889634);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("LOG10E"))) {
|
| + constant = New<HConstant>(0.4342944819032518);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("PI"))) {
|
| + constant = New<HConstant>(3.141592653589793);
|
| + } else if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("SQRT1_2"))) {
|
| + constant = New<HConstant>(0.7071067811865476);
|
| + }
|
| +
|
| + if (constant != NULL) {
|
| + Handle<Map> map(current_info()->global_object()->map());
|
| + map->AddDependentCompilationInfo(DependentCode::kMathConstantGroup,
|
| + current_info());
|
| + ast_context()->ReturnInstruction(constant, expr->id());
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| HInstruction* HOptimizedGraphBuilder::BuildNamedAccess(
|
| PropertyAccessType access,
|
| BailoutId ast_id,
|
| @@ -6735,7 +6806,7 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
|
| ASSERT(current_block() != NULL);
|
| ASSERT(current_block()->HasPredecessor());
|
|
|
| - if (TryArgumentsAccess(expr)) return;
|
| + if (TryArgumentsAccess(expr) || TryMathConstant(expr)) return;
|
|
|
| CHECK_ALIVE(VisitForValue(expr->obj()));
|
| if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) ||
|
|
|