Convert CONSTANT_FUNCTION to CONSTANT
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 24 Jul 2013 12:34:50 +0000 (12:34 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 24 Jul 2013 12:34:50 +0000 (12:34 +0000)
R=yangguo@chromium.org

Review URL: https://chromiumcodereview.appspot.com/19485008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15858 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

24 files changed:
src/arm/lithium-codegen-arm.cc
src/arm/stub-cache-arm.cc
src/ast.cc
src/bootstrapper.cc
src/heap-snapshot-generator.cc
src/hydrogen-instructions.cc
src/hydrogen.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-codegen-ia32.h
src/ia32/stub-cache-ia32.cc
src/ic.cc
src/mirror-debugger.js
src/objects-inl.h
src/objects-printer.cc
src/objects.cc
src/objects.h
src/property-details.h
src/property.cc
src/property.h
src/runtime.cc
src/stub-cache.cc
src/stub-cache.h
src/x64/lithium-codegen-x64.cc
src/x64/stub-cache-x64.cc

index 1463166..192add0 100644 (file)
@@ -426,11 +426,7 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
       Abort("EmitLoadRegister: Unsupported double immediate.");
     } else {
       ASSERT(r.IsTagged());
-      if (literal->IsSmi()) {
-        __ mov(scratch, Operand(literal));
-      } else {
-       __ LoadHeapObject(scratch, Handle<HeapObject>::cast(literal));
-      }
+      __ LoadObject(scratch, literal);
     }
     return scratch;
   } else if (op->IsStackSlot() || op->IsArgument()) {
@@ -1800,12 +1796,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
 void LCodeGen::DoConstantT(LConstantT* instr) {
   Handle<Object> value = instr->value();
   AllowDeferredHandleDereference smi_check;
-  if (value->IsSmi()) {
-    __ mov(ToRegister(instr->result()), Operand(value));
-  } else {
-    __ LoadHeapObject(ToRegister(instr->result()),
-                      Handle<HeapObject>::cast(value));
-  }
+  __ LoadObject(ToRegister(instr->result()), value);
 }
 
 
@@ -3018,9 +3009,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
       __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
       __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
     }
-  } else if (lookup.IsConstantFunction()) {
-    Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
-    __ LoadHeapObject(result, function);
+  } else if (lookup.IsConstant()) {
+    Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
+    __ LoadObject(result, constant);
   } else {
     // Negative lookup.
     // Check prototypes.
index d7b1b55..ccf83f7 100644 (file)
@@ -479,10 +479,9 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   Representation representation = details.representation();
   ASSERT(!representation.IsNone());
 
-  if (details.type() == CONSTANT_FUNCTION) {
-    Handle<HeapObject> constant(
-        HeapObject::cast(descriptors->GetValue(descriptor)));
-    __ LoadHeapObject(scratch1, constant);
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
+    __ LoadObject(scratch1, constant);
     __ cmp(value_reg, scratch1);
     __ b(ne, miss_label);
   } else if (FLAG_track_fields && representation.IsSmi()) {
@@ -543,7 +542,7 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
                       OMIT_REMEMBERED_SET,
                       OMIT_SMI_CHECK);
 
-  if (details.type() == CONSTANT_FUNCTION) {
+  if (details.type() == CONSTANT) {
     ASSERT(value_reg.is(r0));
     __ Ret();
     return;
@@ -1399,9 +1398,9 @@ void BaseLoadStubCompiler::GenerateLoadField(Register reg,
 }
 
 
-void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) {
+void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
   // Return the constant value.
-  __ LoadHeapObject(r0, value);
+  __ LoadObject(r0, value);
   __ Ret();
 }
 
@@ -2670,7 +2669,7 @@ Handle<Code> CallStubCompiler::CompileCallConstant(
     Handle<Code> code = CompileCustomCall(object, holder,
                                           Handle<Cell>::null(),
                                           function, Handle<String>::cast(name),
-                                          Code::CONSTANT_FUNCTION);
+                                          Code::CONSTANT);
     // A null handle means bail out to the regular compiler code below.
     if (!code.is_null()) return code;
   }
index f34c7bb..e0bca67 100644 (file)
@@ -565,11 +565,16 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
     type->LookupDescriptor(NULL, *name, &lookup);
     if (lookup.IsFound()) {
       switch (lookup.type()) {
-        case CONSTANT_FUNCTION:
+        case CONSTANT: {
           // We surely know the target for a constant function.
-          target_ =
-              Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
-          return true;
+          Handle<Object> constant(lookup.GetConstantFromMap(*type),
+                                  type->GetIsolate());
+          if (constant->IsJSFunction()) {
+            target_ = Handle<JSFunction>::cast(constant);
+            return true;
+          }
+          // Fall through.
+        }
         case NORMAL:
         case FIELD:
         case CALLBACKS:
index 281f8b9..dda5fe4 100644 (file)
@@ -1095,12 +1095,12 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
                            JSObject::SetLocalPropertyIgnoreAttributes(
                                result, factory->length_string(),
                                factory->undefined_value(), DONT_ENUM,
-                               Object::FORCE_TAGGED));
+                               Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD));
     CHECK_NOT_EMPTY_HANDLE(isolate,
                            JSObject::SetLocalPropertyIgnoreAttributes(
                                result, factory->callee_string(),
                                factory->undefined_value(), DONT_ENUM,
-                               Object::FORCE_TAGGED));
+                               Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD));
 
 #ifdef DEBUG
     LookupResult lookup(isolate);
@@ -2475,14 +2475,13 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
                                      to, key, value, details.attributes()));
           break;
         }
-        case CONSTANT_FUNCTION: {
+        case CONSTANT: {
           HandleScope inner(isolate());
           Handle<Name> key = Handle<Name>(descs->GetKey(i));
-          Handle<JSFunction> fun =
-              Handle<JSFunction>(descs->GetConstantFunction(i));
+          Handle<Object> constant(descs->GetConstant(i), isolate());
           CHECK_NOT_EMPTY_HANDLE(isolate(),
                                  JSObject::SetLocalPropertyIgnoreAttributes(
-                                     to, key, fun, details.attributes()));
+                                     to, key, constant, details.attributes()));
           break;
         }
         case CALLBACKS: {
index 3b1f235..9f9f84a 100644 (file)
@@ -1339,10 +1339,10 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
           }
           break;
         }
-        case CONSTANT_FUNCTION:
+        case CONSTANT:
           SetPropertyReference(
               js_obj, entry,
-              descs->GetKey(i), descs->GetConstantFunction(i));
+              descs->GetKey(i), descs->GetConstant(i));
           break;
         case CALLBACKS:
           ExtractAccessorPairProperty(
index 52612ac..7af0222 100644 (file)
@@ -2723,7 +2723,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
           types_.Add(types->at(i), zone);
           break;
         }
-        case CONSTANT_FUNCTION:
+        case CONSTANT:
           types_.Add(types->at(i), zone);
           break;
         case CALLBACKS:
index 610cb87..39e9860 100644 (file)
@@ -5459,10 +5459,10 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
   }
 
   // Handle a load of a constant known function.
-  if (lookup.IsConstantFunction()) {
+  if (lookup.IsConstant()) {
     AddCheckMap(object, map);
-    Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
-    return new(zone()) HConstant(function);
+    Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
+    return new(zone()) HConstant(constant);
   }
 
   // Handle a load from a known field somewhere in the prototype chain.
@@ -5480,14 +5480,14 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
   }
 
   // Handle a load of a constant function somewhere in the prototype chain.
-  if (lookup.IsConstantFunction()) {
+  if (lookup.IsConstant()) {
     Handle<JSObject> prototype(JSObject::cast(map->prototype()));
     Handle<JSObject> holder(lookup.holder());
     Handle<Map> holder_map(holder->map());
     AddCheckMap(object, map);
     Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
-    Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
-    return new(zone()) HConstant(function);
+    Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate());
+    return new(zone()) HConstant(constant);
   }
 
   // No luck, do a generic load.
index 8f7b8ff..50642de 100644 (file)
@@ -1836,11 +1836,7 @@ void LCodeGen::DoConstantT(LConstantT* instr) {
   Register reg = ToRegister(instr->result());
   Handle<Object> handle = instr->value();
   AllowDeferredHandleDereference smi_check;
-  if (handle->IsHeapObject()) {
-    __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle));
-  } else {
-    __ Set(reg, Immediate(handle));
-  }
+  __ LoadObject(reg, handle);
 }
 
 
@@ -3060,11 +3056,11 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
 }
 
 
-void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
-                                               Register object,
-                                               Handle<Map> type,
-                                               Handle<String> name,
-                                               LEnvironment* env) {
+void LCodeGen::EmitLoadFieldOrConstant(Register result,
+                                       Register object,
+                                       Handle<Map> type,
+                                       Handle<String> name,
+                                       LEnvironment* env) {
   LookupResult lookup(isolate());
   type->LookupDescriptor(NULL, *name, &lookup);
   ASSERT(lookup.IsFound() || lookup.IsCacheable());
@@ -3080,9 +3076,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
       __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
       __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
     }
-  } else if (lookup.IsConstantFunction()) {
-    Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
-    __ LoadHeapObject(result, function);
+  } else if (lookup.IsConstant()) {
+    Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
+    __ LoadObject(result, constant);
   } else {
     // Negative lookup.
     // Check prototypes.
@@ -3131,7 +3127,7 @@ static bool CompactEmit(SmallMapList* list,
   if (map->HasElementsTransition()) return false;
   LookupResult lookup(isolate);
   map->LookupDescriptor(NULL, *name, &lookup);
-  return lookup.IsField() || lookup.IsConstantFunction();
+  return lookup.IsField() || lookup.IsConstant();
 }
 
 
@@ -3163,16 +3159,14 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
     if (last && !need_generic) {
       DeoptimizeIf(not_equal, instr->environment());
       __ bind(&check_passed);
-      EmitLoadFieldOrConstantFunction(
-          result, object, map, name, instr->environment());
+      EmitLoadFieldOrConstant(result, object, map, name, instr->environment());
     } else {
       Label next;
       bool compact = all_are_compact ? true :
           CompactEmit(instr->hydrogen()->types(), name, i, isolate());
       __ j(not_equal, &next, compact ? Label::kNear : Label::kFar);
       __ bind(&check_passed);
-      EmitLoadFieldOrConstantFunction(
-          result, object, map, name, instr->environment());
+      EmitLoadFieldOrConstant(result, object, map, name, instr->environment());
       __ jmp(&done, all_are_compact ? Label::kNear : Label::kFar);
       __ bind(&next);
     }
index 30b889f..f2107ec 100644 (file)
@@ -370,11 +370,11 @@ class LCodeGen BASE_EMBEDDED {
   // Caller should branch on equal condition.
   void EmitIsConstructCall(Register temp);
 
-  void EmitLoadFieldOrConstantFunction(Register result,
-                                       Register object,
-                                       Handle<Map> type,
-                                       Handle<String> name,
-                                       LEnvironment* env);
+  void EmitLoadFieldOrConstant(Register result,
+                               Register object,
+                               Handle<Map> type,
+                               Handle<String> name,
+                               LEnvironment* env);
 
   // Emits optimized code to deep-copy the contents of statically known
   // object graphs (e.g. object literal boilerplate).
index 2b391e0..123506f 100644 (file)
@@ -816,11 +816,9 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   Representation representation = details.representation();
   ASSERT(!representation.IsNone());
 
-  if (details.type() == CONSTANT_FUNCTION) {
-    Handle<HeapObject> constant(
-        HeapObject::cast(descriptors->GetValue(descriptor)));
-    __ LoadHeapObject(scratch1, constant);
-    __ cmp(value_reg, scratch1);
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
+    __ CmpObject(value_reg, constant);
     __ j(not_equal, miss_label);
   } else if (FLAG_track_fields && representation.IsSmi()) {
       __ JumpIfNotSmi(value_reg, miss_label);
@@ -897,7 +895,7 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
                       OMIT_REMEMBERED_SET,
                       OMIT_SMI_CHECK);
 
-  if (details.type() == CONSTANT_FUNCTION) {
+  if (details.type() == CONSTANT) {
     ASSERT(value_reg.is(eax));
     __ ret(0);
     return;
@@ -1428,9 +1426,9 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
 }
 
 
-void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) {
+void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
   // Return the constant value.
-  __ LoadHeapObject(eax, value);
+  __ LoadObject(eax, value);
   __ ret(0);
 }
 
@@ -2727,7 +2725,7 @@ Handle<Code> CallStubCompiler::CompileCallConstant(
     Handle<Code> code = CompileCustomCall(object, holder,
                                           Handle<Cell>::null(),
                                           function, Handle<String>::cast(name),
-                                          Code::CONSTANT_FUNCTION);
+                                          Code::CONSTANT);
     // A null handle means bail out to the regular compiler code below.
     if (!code.is_null()) return code;
   }
index f0f5c30..269754b 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -634,7 +634,7 @@ bool CallICBase::TryUpdateExtraICState(LookupResult* lookup,
                                        Handle<Object> object,
                                        Code::ExtraICState* extra_ic_state) {
   ASSERT(kind_ == Code::CALL_IC);
-  if (lookup->type() != CONSTANT_FUNCTION) return false;
+  if (!lookup->IsConstantFunction()) return false;
   JSFunction* function = lookup->GetConstantFunction();
   if (!function->shared()->HasBuiltinFunctionId()) return false;
 
@@ -687,7 +687,8 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
       return isolate()->stub_cache()->ComputeCallField(
           argc, kind_, extra_state, name, object, holder, index);
     }
-    case CONSTANT_FUNCTION: {
+    case CONSTANT: {
+      if (!lookup->IsConstantFunction()) return Handle<Code>::null();
       // Get the constant function and compute the code stub for this
       // call; used for rewriting to monomorphic state and making sure
       // that the code stub is in the stub cache.
@@ -1312,8 +1313,11 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
       return isolate()->stub_cache()->ComputeLoadField(
           name, receiver, holder,
           lookup->GetFieldIndex(), lookup->representation());
-    case CONSTANT_FUNCTION: {
-      Handle<JSFunction> constant(lookup->GetConstantFunction());
+    case CONSTANT: {
+      Handle<Object> constant(lookup->GetConstant(), isolate());
+      // TODO(2803): Don't compute a stub for cons strings because they cannot
+      // be embedded into code.
+      if (constant->IsConsString()) return Handle<Code>::null();
       return isolate()->stub_cache()->ComputeLoadConstant(
           name, receiver, holder, constant);
     }
@@ -1522,8 +1526,11 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
       return isolate()->stub_cache()->ComputeKeyedLoadField(
           name, receiver, holder,
           lookup->GetFieldIndex(), lookup->representation());
-    case CONSTANT_FUNCTION: {
-      Handle<JSFunction> constant(lookup->GetConstantFunction(), isolate());
+    case CONSTANT: {
+      Handle<Object> constant(lookup->GetConstant(), isolate());
+      // TODO(2803): Don't compute a stub for cons strings because they cannot
+      // be embedded into code.
+      if (constant->IsConsString()) return Handle<Code>::null();
       return isolate()->stub_cache()->ComputeKeyedLoadConstant(
           name, receiver, holder, constant);
     }
@@ -1798,7 +1805,7 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
       ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
       return isolate()->stub_cache()->ComputeStoreInterceptor(
           name, receiver, strict_mode);
-    case CONSTANT_FUNCTION:
+    case CONSTANT:
       break;
     case TRANSITION: {
       // Explicitly pass in the receiver map since LookupForWrite may have
@@ -2184,7 +2191,7 @@ Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
       // fall through.
     }
     case NORMAL:
-    case CONSTANT_FUNCTION:
+    case CONSTANT:
     case CALLBACKS:
     case INTERCEPTOR:
       // Always rewrite to the generic case so that we do not
index 28ef24d..3b360bb 100644 (file)
@@ -173,7 +173,7 @@ PropertyKind.Indexed = 2;
 var PropertyType = {};
 PropertyType.Normal                  = 0;
 PropertyType.Field                   = 1;
-PropertyType.ConstantFunction        = 2;
+PropertyType.Constant                = 2;
 PropertyType.Callbacks               = 3;
 PropertyType.Handler                 = 4;
 PropertyType.Interceptor             = 5;
index a1c1d83..3189d84 100644 (file)
@@ -2352,8 +2352,8 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) {
 }
 
 
-JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
-  return JSFunction::cast(GetValue(descriptor_number));
+Object* DescriptorArray::GetConstant(int descriptor_number) {
+  return GetValue(descriptor_number);
 }
 
 
@@ -3648,7 +3648,7 @@ bool Map::CanBeDeprecated() {
         details.representation().IsHeapObject()) {
       return true;
     }
-    if (FLAG_track_fields && details.type() == CONSTANT_FUNCTION) {
+    if (FLAG_track_fields && details.type() == CONSTANT) {
       return true;
     }
   }
index 91b1c2e..2327cba 100644 (file)
@@ -294,9 +294,9 @@ void JSObject::PrintProperties(FILE* out) {
           PrintF(out, " (field at offset %d)\n", index);
           break;
         }
-        case CONSTANT_FUNCTION:
-          descs->GetConstantFunction(i)->ShortPrint(out);
-          PrintF(out, " (constant function)\n");
+        case CONSTANT:
+          descs->GetConstant(i)->ShortPrint(out);
+          PrintF(out, " (constant)\n");
           break;
         case CALLBACKS:
           descs->GetCallbacksObject(i)->ShortPrint(out);
@@ -450,8 +450,8 @@ void JSObject::PrintTransitions(FILE* out) {
         PrintF(out, " (transition to field)\n");
         break;
       }
-      case CONSTANT_FUNCTION:
-        PrintF(out, " (transition to constant function)\n");
+      case CONSTANT:
+        PrintF(out, " (transition to constant)\n");
         break;
       case CALLBACKS:
         PrintF(out, " (transition to callback)\n");
@@ -1262,8 +1262,8 @@ void TransitionArray::PrintTransitions(FILE* out) {
         PrintF(out, " (transition to field)\n");
         break;
       }
-      case CONSTANT_FUNCTION:
-        PrintF(out, " (transition to constant function)\n");
+      case CONSTANT:
+        PrintF(out, " (transition to constant)\n");
         break;
       case CALLBACKS:
         PrintF(out, " (transition to callback)\n");
index b83aea4..7839faa 100644 (file)
@@ -518,7 +518,7 @@ MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
       }
       case NORMAL:
       case FIELD:
-      case CONSTANT_FUNCTION: {
+      case CONSTANT: {
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r(GetIsolate());
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
@@ -579,7 +579,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
 
       case NORMAL:
       case FIELD:
-      case CONSTANT_FUNCTION: {
+      case CONSTANT: {
         if (!continue_search) break;
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r(GetIsolate());
@@ -874,8 +874,8 @@ MaybeObject* Object::GetProperty(Object* receiver,
       ASSERT(!value->IsTheHole() || result->IsReadOnly());
       return value->IsTheHole() ? heap->undefined_value() : value;
     }
-    case CONSTANT_FUNCTION:
-      return result->GetConstantFunction();
+    case CONSTANT:
+      return result->GetConstant();
     case CALLBACKS:
       return result->holder()->GetPropertyWithCallback(
           receiver, result->GetCallbackObject(), name);
@@ -1927,12 +1927,12 @@ MaybeObject* JSObject::AddFastProperty(Name* name,
 }
 
 
-MaybeObject* JSObject::AddConstantFunctionProperty(
+MaybeObject* JSObject::AddConstantProperty(
     Name* name,
-    JSFunction* function,
+    Object* constant,
     PropertyAttributes attributes) {
-  // Allocate new instance descriptors with (name, function) added
-  ConstantFunctionDescriptor d(name, function, attributes);
+  // Allocate new instance descriptors with (name, constant) added
+  ConstantDescriptor d(name, constant, attributes);
 
   TransitionFlag flag =
       // Do not add transitions to  global objects.
@@ -1948,7 +1948,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
   if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 
   set_map(new_map);
-  return function;
+  return constant;
 }
 
 
@@ -2000,7 +2000,8 @@ MaybeObject* JSObject::AddProperty(Name* name,
                                    StrictModeFlag strict_mode,
                                    JSReceiver::StoreFromKeyed store_mode,
                                    ExtensibilityCheck extensibility_check,
-                                   ValueType value_type) {
+                                   ValueType value_type,
+                                   StoreMode mode) {
   ASSERT(!IsJSGlobalProxy());
   Map* map_of_this = map();
   Heap* heap = GetHeap();
@@ -2022,10 +2023,12 @@ MaybeObject* JSObject::AddProperty(Name* name,
     // Ensure the descriptor array does not get too big.
     if (map_of_this->NumberOfOwnDescriptors() <
         DescriptorArray::kMaxNumberOfDescriptors) {
+      // TODO(verwaest): Support other constants.
+      // if (mode == ALLOW_AS_CONSTANT &&
+      //     !value->IsTheHole() &&
+      //     !value->IsConsString()) {
       if (value->IsJSFunction()) {
-        result = AddConstantFunctionProperty(name,
-                                             JSFunction::cast(value),
-                                             attributes);
+        result = AddConstantProperty(name, value, attributes);
       } else {
         result = AddFastProperty(
             name, value, attributes, store_mode, value_type);
@@ -2095,7 +2098,8 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
     Object* value,
     PropertyAttributes attributes,
     StrictModeFlag strict_mode,
-    ExtensibilityCheck extensibility_check) {
+    ExtensibilityCheck extensibility_check,
+    StoreMode mode) {
   // Check local property, ignore interceptor.
   LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
@@ -2112,7 +2116,8 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
   if (done) return result_object;
   // Add a new real property.
   return AddProperty(name, value, attributes, strict_mode,
-                     MAY_BE_STORE_FROM_KEYED, extensibility_check);
+                     MAY_BE_STORE_FROM_KEYED, extensibility_check,
+                     OPTIMAL_REPRESENTATION, mode);
 }
 
 
@@ -2377,9 +2382,9 @@ MaybeObject* JSObject::MigrateToMap(Map* new_map) {
     PropertyDetails details = new_descriptors->GetDetails(i);
     if (details.type() != FIELD) continue;
     PropertyDetails old_details = old_descriptors->GetDetails(i);
-    ASSERT(old_details.type() == CONSTANT_FUNCTION ||
+    ASSERT(old_details.type() == CONSTANT ||
            old_details.type() == FIELD);
-    Object* value = old_details.type() == CONSTANT_FUNCTION
+    Object* value = old_details.type() == CONSTANT
         ? old_descriptors->GetValue(i)
         : RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
     if (FLAG_track_double_fields &&
@@ -2994,7 +2999,7 @@ MaybeObject* JSObject::SetPropertyViaPrototypes(
     switch (result.type()) {
       case NORMAL:
       case FIELD:
-      case CONSTANT_FUNCTION:
+      case CONSTANT:
         *done = result.IsReadOnly();
         break;
       case INTERCEPTOR: {
@@ -3867,13 +3872,13 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
       result = *value;
       break;
     }
-    case CONSTANT_FUNCTION:
-      // Only replace the function if necessary.
-      if (*value == lookup->GetConstantFunction()) return *value;
+    case CONSTANT:
+      // Only replace the constant if necessary.
+      if (*value == lookup->GetConstant()) return *value;
       // Preserve the attributes of this existing property.
       attributes = lookup->GetAttributes();
-      result =
-          lookup->holder()->ConvertDescriptorToField(*name, *value, attributes);
+      result = lookup->holder()->ConvertDescriptorToField(
+          *name, *value, attributes);
       break;
     case CALLBACKS: {
       Object* callback_object = lookup->GetCallbackObject();
@@ -3919,14 +3924,14 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
         result = lookup->holder()->ConvertDescriptorToField(
             *name, *value, attributes);
       } else {
-        ASSERT(details.type() == CONSTANT_FUNCTION);
+        ASSERT(details.type() == CONSTANT);
 
-        Object* constant_function = descriptors->GetValue(descriptor);
-        if (constant_function == *value) {
+        Object* constant = descriptors->GetValue(descriptor);
+        if (constant == *value) {
           // If the same constant function is being added we can simply
           // transition to the target map.
           lookup->holder()->set_map(transition_map);
-          result = constant_function;
+          result = constant;
         } else {
           // Otherwise, replace with a map transition to a new map with a FIELD,
           // even if the value is a constant function.
@@ -3977,11 +3982,12 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
     Handle<Name> key,
     Handle<Object> value,
     PropertyAttributes attributes,
-    ValueType value_type) {
+    ValueType value_type,
+    StoreMode mode) {
   CALL_HEAP_FUNCTION(
     object->GetIsolate(),
     object->SetLocalPropertyIgnoreAttributes(
-        *key, *value, attributes, value_type),
+        *key, *value, attributes, value_type, mode),
     Object);
 }
 
@@ -3990,7 +3996,8 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
     Name* name_raw,
     Object* value_raw,
     PropertyAttributes attributes,
-    ValueType value_type) {
+    ValueType value_type,
+    StoreMode mode) {
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc;
@@ -4017,7 +4024,8 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
         name_raw,
         value_raw,
         attributes,
-        value_type);
+        value_type,
+        mode);
   }
 
   // Check for accessor in prototype chain removed here in clone.
@@ -4025,7 +4033,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
     // Neither properties nor transitions found.
     return AddProperty(
         name_raw, value_raw, attributes, kNonStrictMode,
-        MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type);
+        MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type, mode);
   }
 
   // From this point on everything needs to be handlified.
@@ -4075,9 +4083,9 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
       result = *value;
       break;
     }
-    case CONSTANT_FUNCTION:
+    case CONSTANT:
       // Only replace the function if necessary.
-      if (*value != lookup.GetConstantFunction()) {
+      if (*value != lookup.GetConstant()) {
         // Preserve the attributes of this existing property.
         attributes = lookup.GetAttributes();
         result = self->ConvertDescriptorToField(*name, *value, attributes);
@@ -4122,7 +4130,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
       } else if (details.type() == CALLBACKS) {
         result = self->ConvertDescriptorToField(*name, *value, attributes);
       } else {
-        ASSERT(details.type() == CONSTANT_FUNCTION);
+        ASSERT(details.type() == CONSTANT);
 
         // Replace transition to CONSTANT FUNCTION with a map transition to a
         // new map with a FIELD, even if the value is a function.
@@ -4264,7 +4272,7 @@ PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
     switch (lookup->type()) {
       case NORMAL:  // fall through
       case FIELD:
-      case CONSTANT_FUNCTION:
+      case CONSTANT:
       case CALLBACKS:
         return lookup->GetAttributes();
       case HANDLER: {
@@ -4504,10 +4512,10 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
   for (int i = 0; i < real_size; i++) {
     PropertyDetails details = descs->GetDetails(i);
     switch (details.type()) {
-      case CONSTANT_FUNCTION: {
+      case CONSTANT: {
         PropertyDetails d = PropertyDetails(
             details.attributes(), NORMAL, i + 1);
-        Object* value = descs->GetConstantFunction(i);
+        Object* value = descs->GetConstant(i);
         MaybeObject* maybe_dictionary =
             dictionary->Add(descs->GetKey(i), value, d);
         if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
@@ -4949,7 +4957,8 @@ MaybeObject* JSObject::GetHiddenPropertiesHashTable(
                                  hashtable,
                                  DONT_ENUM,
                                  kNonStrictMode,
-                                 OMIT_EXTENSIBILITY_CHECK);
+                                 OMIT_EXTENSIBILITY_CHECK,
+                                 FORCE_FIELD);
   if (store_result->IsFailure()) return store_result;
   return hashtable;
 }
@@ -4981,7 +4990,8 @@ MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) {
                                  value,
                                  DONT_ENUM,
                                  kNonStrictMode,
-                                 OMIT_EXTENSIBILITY_CHECK);
+                                 OMIT_EXTENSIBILITY_CHECK,
+                                 FORCE_FIELD);
   if (store_result->IsFailure()) return store_result;
   return this;
 }
@@ -6457,8 +6467,8 @@ Object* JSObject::SlowReverseLookup(Object* value) {
         } else if (property == value) {
           return descs->GetKey(i);
         }
-      } else if (descs->GetType(i) == CONSTANT_FUNCTION) {
-        if (descs->GetConstantFunction(i) == value) {
+      } else if (descs->GetType(i) == CONSTANT) {
+        if (descs->GetConstant(i) == value) {
           return descs->GetKey(i);
         }
       }
@@ -7800,8 +7810,8 @@ MaybeObject* DescriptorArray::Merge(int verbatim,
     PropertyDetails other_details = other->GetDetails(descriptor);
 
     if (details.type() == FIELD || other_details.type() == FIELD ||
-        (details.type() == CONSTANT_FUNCTION &&
-         other_details.type() == CONSTANT_FUNCTION &&
+        (details.type() == CONSTANT &&
+         other_details.type() == CONSTANT &&
          GetValue(descriptor) != other->GetValue(descriptor))) {
       Representation representation =
           details.representation().generalize(other_details.representation());
@@ -7850,8 +7860,8 @@ bool DescriptorArray::IsMoreGeneralThan(int verbatim,
     if (!other_details.representation().fits_into(details.representation())) {
       return false;
     }
-    if (details.type() == CONSTANT_FUNCTION) {
-      if (other_details.type() != CONSTANT_FUNCTION) return false;
+    if (details.type() == CONSTANT) {
+      if (other_details.type() != CONSTANT) return false;
       if (GetValue(descriptor) != other->GetValue(descriptor)) return false;
     }
   }
@@ -10688,7 +10698,7 @@ const char* Code::StubType2String(StubType type) {
   switch (type) {
     case NORMAL: return "NORMAL";
     case FIELD: return "FIELD";
-    case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION";
+    case CONSTANT: return "CONSTANT";
     case CALLBACKS: return "CALLBACKS";
     case INTERCEPTOR: return "INTERCEPTOR";
     case MAP_TRANSITION: return "MAP_TRANSITION";
@@ -15264,9 +15274,7 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor(
       PropertyType type = details.type();
 
       if (value->IsJSFunction()) {
-        ConstantFunctionDescriptor d(key,
-                                     JSFunction::cast(value),
-                                     details.attributes());
+        ConstantDescriptor d(key, value, details.attributes());
         descriptors->Set(enumeration_index - 1, &d, witness);
       } else if (type == NORMAL) {
         if (current_offset < inobject_props) {
@@ -15913,6 +15921,8 @@ Type* PropertyCell::UpdateType(Handle<PropertyCell> cell,
                                Handle<Object> value) {
   Isolate* isolate = cell->GetIsolate();
   Handle<Type> old_type(cell->type(), isolate);
+  // TODO(2803): Do not track ConsString as constant because they cannot be
+  // embedded into code.
   Handle<Type> new_type(value->IsConsString() || value->IsTheHole()
                         ? Type::Any()
                         : Type::Constant(value, isolate), isolate);
index bb9cee6..36611ee 100644 (file)
@@ -1644,6 +1644,12 @@ class JSReceiver: public HeapObject {
     CERTAINLY_NOT_STORE_FROM_KEYED
   };
 
+  // Indicates whether a value can be loaded as a constant.
+  enum StoreMode {
+    ALLOW_AS_CONSTANT,
+    FORCE_FIELD
+  };
+
   // Internal properties (e.g. the hidden properties dictionary) might
   // be added even though the receiver is non-extensible.
   enum ExtensibilityCheck {
@@ -1871,14 +1877,16 @@ class JSObject: public JSReceiver {
       Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode,
-      ExtensibilityCheck extensibility_check);
+      ExtensibilityCheck extensibility_check,
+      StoreMode mode = ALLOW_AS_CONSTANT);
 
   static Handle<Object> SetLocalPropertyIgnoreAttributes(
       Handle<JSObject> object,
       Handle<Name> key,
       Handle<Object> value,
       PropertyAttributes attributes,
-      ValueType value_type = OPTIMAL_REPRESENTATION);
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT);
 
   static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
   static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
@@ -1906,7 +1914,8 @@ class JSObject: public JSReceiver {
       Name* key,
       Object* value,
       PropertyAttributes attributes,
-      ValueType value_type = OPTIMAL_REPRESENTATION);
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT);
 
   // Retrieve a value in a normalized object given a lookup result.
   // Handles the special representation of JS global objects.
@@ -2205,9 +2214,9 @@ class JSObject: public JSReceiver {
   // normal property is added instead, with a map transition.
   // This avoids the creation of many maps with the same constant
   // function, all orphaned.
-  MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty(
+  MUST_USE_RESULT MaybeObject* AddConstantProperty(
       Name* name,
-      JSFunction* function,
+      Object* constant,
       PropertyAttributes attributes);
 
   MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
@@ -2272,7 +2281,8 @@ class JSObject: public JSReceiver {
       StrictModeFlag strict_mode,
       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
       ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
-      ValueType value_type = OPTIMAL_REPRESENTATION);
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT);
 
   // Convert the object to use the canonical dictionary
   // representation. If the object is expected to have additional properties
@@ -2863,7 +2873,7 @@ class DescriptorArray: public FixedArray {
   inline PropertyDetails GetDetails(int descriptor_number);
   inline PropertyType GetType(int descriptor_number);
   inline int GetFieldIndex(int descriptor_number);
-  inline JSFunction* GetConstantFunction(int descriptor_number);
+  inline Object* GetConstant(int descriptor_number);
   inline Object* GetCallbacksObject(int descriptor_number);
   inline AccessorDescriptor* GetCallbacks(int descriptor_number);
 
@@ -4518,7 +4528,7 @@ class Code: public HeapObject {
   enum StubType {
     NORMAL,
     FIELD,
-    CONSTANT_FUNCTION,
+    CONSTANT,
     CALLBACKS,
     INTERCEPTOR,
     MAP_TRANSITION,
index ac36563..6b62ddb 100644 (file)
@@ -67,7 +67,7 @@ enum PropertyType {
   NORMAL                    = 0,
   // Only in fast mode.
   FIELD                     = 1,
-  CONSTANT_FUNCTION         = 2,
+  CONSTANT                  = 2,
   CALLBACKS                 = 3,
   // Only in lookup results, not in descriptors.
   HANDLER                   = 4,
index 80a06cb..83a6a36 100644 (file)
@@ -55,10 +55,10 @@ void LookupResult::Print(FILE* out) {
       PrintF(out, " -type = normal\n");
       PrintF(out, " -entry = %d", GetDictionaryEntry());
       break;
-    case CONSTANT_FUNCTION:
-      PrintF(out, " -type = constant function\n");
-      PrintF(out, " -function:\n");
-      GetConstantFunction()->Print(out);
+    case CONSTANT:
+      PrintF(out, " -type = constant\n");
+      PrintF(out, " -value:\n");
+      GetConstant()->Print(out);
       PrintF(out, "\n");
       break;
     case FIELD:
@@ -85,7 +85,7 @@ void LookupResult::Print(FILE* out) {
           GetTransitionMap()->Print(out);
           PrintF(out, "\n");
           return;
-        case CONSTANT_FUNCTION:
+        case CONSTANT:
           PrintF(out, " -type = constant property transition\n");
           PrintF(out, " -map:\n");
           GetTransitionMap()->Print(out);
index 5213ee6..d109de9 100644 (file)
@@ -106,13 +106,13 @@ class FieldDescriptor: public Descriptor {
 };
 
 
-class ConstantFunctionDescriptor: public Descriptor {
+class ConstantDescriptor: public Descriptor {
  public:
-  ConstantFunctionDescriptor(Name* key,
-                             JSFunction* function,
-                             PropertyAttributes attributes)
-      : Descriptor(key, function, attributes, CONSTANT_FUNCTION,
-                   Representation::HeapObject()) {}
+  ConstantDescriptor(Name* key,
+                     Object* value,
+                     PropertyAttributes attributes)
+      : Descriptor(key, value, attributes, CONSTANT,
+                   value->OptimalRepresentation()) {}
 };
 
 
@@ -303,9 +303,13 @@ class LookupResult BASE_EMBEDDED {
     return details_.type() == NORMAL;
   }
 
+  bool IsConstant() {
+    ASSERT(!(details_.type() == CONSTANT && !IsFound()));
+    return details_.type() == CONSTANT;
+  }
+
   bool IsConstantFunction() {
-    ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound()));
-    return details_.type() == CONSTANT_FUNCTION;
+    return IsConstant() && GetValue()->IsJSFunction();
   }
 
   bool IsDontDelete() { return details_.IsDontDelete(); }
@@ -324,7 +328,7 @@ class LookupResult BASE_EMBEDDED {
     switch (type()) {
       case FIELD:
       case NORMAL:
-      case CONSTANT_FUNCTION:
+      case CONSTANT:
         return true;
       case CALLBACKS: {
         Object* callback = GetCallbackObject();
@@ -355,8 +359,8 @@ class LookupResult BASE_EMBEDDED {
         }
         return value;
       }
-      case CONSTANT_FUNCTION:
-        return GetConstantFunction();
+      case CONSTANT:
+        return GetConstant();
       case CALLBACKS:
       case HANDLER:
       case INTERCEPTOR:
@@ -392,9 +396,8 @@ class LookupResult BASE_EMBEDDED {
     return IsTransition() && GetTransitionDetails(map).type() == FIELD;
   }
 
-  bool IsTransitionToConstantFunction(Map* map) {
-    return IsTransition() &&
-        GetTransitionDetails(map).type() == CONSTANT_FUNCTION;
+  bool IsTransitionToConstant(Map* map) {
+    return IsTransition() && GetTransitionDetails(map).type() == CONSTANT;
   }
 
   Map* GetTransitionMap() {
@@ -434,13 +437,22 @@ class LookupResult BASE_EMBEDDED {
   }
 
   JSFunction* GetConstantFunction() {
-    ASSERT(type() == CONSTANT_FUNCTION);
+    ASSERT(type() == CONSTANT);
     return JSFunction::cast(GetValue());
   }
 
+  Object* GetConstantFromMap(Map* map) {
+    ASSERT(type() == CONSTANT);
+    return GetValueFromMap(map);
+  }
+
   JSFunction* GetConstantFunctionFromMap(Map* map) {
-    ASSERT(type() == CONSTANT_FUNCTION);
-    return JSFunction::cast(GetValueFromMap(map));
+    return JSFunction::cast(GetConstantFromMap(map));
+  }
+
+  Object* GetConstant() {
+    ASSERT(type() == CONSTANT);
+    return GetValue();
   }
 
   Object* GetCallbackObject() {
index ddfa474..37eaf29 100644 (file)
@@ -265,6 +265,9 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
     }
     Handle<Object> result;
     uint32_t element_index = 0;
+    JSReceiver::StoreMode mode = value->IsJSObject()
+        ? JSReceiver::FORCE_FIELD
+        : JSReceiver::ALLOW_AS_CONSTANT;
     if (key->IsInternalizedString()) {
       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
         // Array index as string (uint32).
@@ -274,7 +277,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
         Handle<String> name(String::cast(*key));
         ASSERT(!name->AsArrayIndex(&element_index));
         result = JSObject::SetLocalPropertyIgnoreAttributes(
-            boilerplate, name, value, NONE);
+            boilerplate, name, value, NONE,
+            Object::OPTIMAL_REPRESENTATION, mode);
       }
     } else if (key->ToArrayIndex(&element_index)) {
       // Array index (uint32).
@@ -290,7 +294,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
       Handle<String> name =
           isolate->factory()->NewStringFromAscii(CStrVector(str));
       result = JSObject::SetLocalPropertyIgnoreAttributes(
-          boilerplate, name, value, NONE);
+          boilerplate, name, value, NONE,
+          Object::OPTIMAL_REPRESENTATION, mode);
     }
     // If setting the property on the boilerplate throws an
     // exception, the exception is converted to an empty handle in
@@ -2203,8 +2208,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
     }
   } else {
     // Ignore re-initialization of constants that have already been
-    // assigned a function value.
-    ASSERT(lookup.IsReadOnly() && lookup.IsConstantFunction());
+    // assigned a constant value.
+    ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
   }
 
   // Use the set value as the result of the operation.
@@ -4969,8 +4974,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
       return lookup.holder()->FastPropertyAt(
           lookup.representation(),
           lookup.GetFieldIndex().field_index());
-    case CONSTANT_FUNCTION:
-      return lookup.GetConstantFunction();
+    case CONSTANT:
+      return lookup.GetConstant();
     case CALLBACKS:
     case HANDLER:
     case INTERCEPTOR:
@@ -10554,8 +10559,8 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
       }
       return value;
     }
-    case CONSTANT_FUNCTION:
-      return result->GetConstantFunction();
+    case CONSTANT:
+      return result->GetConstant();
     case CALLBACKS: {
       Object* structure = result->GetCallbackObject();
       if (structure->IsForeign() || structure->IsAccessorInfo()) {
index d554d0c..73c7a0a 100644 (file)
@@ -335,10 +335,10 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
                                             Handle<JSObject> receiver,
                                             Handle<JSObject> holder,
-                                            Handle<JSFunction> value) {
+                                            Handle<Object> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> handler = FindLoadHandler(
-      name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
+      name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT);
   if (!handler.is_null()) return handler;
 
   LoadStubCompiler compiler(isolate_);
@@ -417,11 +417,11 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
                                                  Handle<JSObject> receiver,
                                                  Handle<JSObject> holder,
-                                                 Handle<JSFunction> value) {
+                                                 Handle<Object> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
   Handle<Code> handler = FindLoadHandler(
       name, receiver, stub_holder, Code::KEYED_LOAD_IC,
-      Code::CONSTANT_FUNCTION);
+      Code::CONSTANT);
   if (!handler.is_null()) return handler;
 
   KeyedLoadStubCompiler compiler(isolate_);
@@ -698,7 +698,7 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
   }
 
   Code::Flags flags = Code::ComputeMonomorphicFlags(
-      kind, extra_state, Code::CONSTANT_FUNCTION, argc, cache_holder);
+      kind, extra_state, Code::CONSTANT, argc, cache_holder);
   Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
                        isolate_);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -1619,14 +1619,14 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
     Handle<JSObject> object,
     Handle<JSObject> holder,
     Handle<Name> name,
-    Handle<JSFunction> value) {
+    Handle<Object> value) {
   Label success;
   HandlerFrontend(object, receiver(), holder, name, &success);
   __ bind(&success);
   GenerateLoadConstant(value);
 
   // Return the generated code.
-  return GetCode(kind(), Code::CONSTANT_FUNCTION, name);
+  return GetCode(kind(), Code::CONSTANT, name);
 }
 
 
@@ -2130,14 +2130,14 @@ Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
   if (function->shared()->name()->IsString()) {
     function_name = Handle<String>(String::cast(function->shared()->name()));
   }
-  return GetCode(Code::CONSTANT_FUNCTION, function_name);
+  return GetCode(Code::CONSTANT, function_name);
 }
 
 
 CallOptimization::CallOptimization(LookupResult* lookup) {
   if (lookup->IsFound() &&
       lookup->IsCacheable() &&
-      lookup->type() == CONSTANT_FUNCTION) {
+      lookup->IsConstantFunction()) {
     // We only optimize constant function calls.
     Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
   } else {
index 73a1a8a..bd0678e 100644 (file)
@@ -144,7 +144,7 @@ class StubCache {
   Handle<Code> ComputeLoadConstant(Handle<Name> name,
                                    Handle<JSObject> object,
                                    Handle<JSObject> holder,
-                                   Handle<JSFunction> value);
+                                   Handle<Object> value);
 
   Handle<Code> ComputeLoadInterceptor(Handle<Name> name,
                                       Handle<JSObject> object,
@@ -176,7 +176,7 @@ class StubCache {
   Handle<Code> ComputeKeyedLoadConstant(Handle<Name> name,
                                         Handle<JSObject> object,
                                         Handle<JSObject> holder,
-                                        Handle<JSFunction> value);
+                                        Handle<Object> value);
 
   Handle<Code> ComputeKeyedLoadInterceptor(Handle<Name> name,
                                            Handle<JSObject> object,
@@ -708,7 +708,7 @@ class BaseLoadStubCompiler: public BaseLoadStoreStubCompiler {
   Handle<Code> CompileLoadConstant(Handle<JSObject> object,
                                    Handle<JSObject> holder,
                                    Handle<Name> name,
-                                   Handle<JSFunction> value);
+                                   Handle<Object> value);
 
   Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
                                       Handle<JSObject> holder,
@@ -741,7 +741,7 @@ class BaseLoadStubCompiler: public BaseLoadStoreStubCompiler {
                          Handle<JSObject> holder,
                          PropertyIndex field,
                          Representation representation);
-  void GenerateLoadConstant(Handle<JSFunction> value);
+  void GenerateLoadConstant(Handle<Object> value);
   void GenerateLoadCallback(Register reg,
                             Handle<ExecutableAccessorInfo> callback);
   void GenerateLoadInterceptor(Register holder_reg,
index 262395a..6a184f8 100644 (file)
@@ -1504,12 +1504,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
 void LCodeGen::DoConstantT(LConstantT* instr) {
   Handle<Object> value = instr->value();
   AllowDeferredHandleDereference smi_check;
-  if (value->IsSmi()) {
-    __ Move(ToRegister(instr->result()), value);
-  } else {
-    __ LoadHeapObject(ToRegister(instr->result()),
-                      Handle<HeapObject>::cast(value));
-  }
+  __ LoadObject(ToRegister(instr->result()), value);
 }
 
 
@@ -2689,9 +2684,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
       __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
       __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
     }
-  } else if (lookup.IsConstantFunction()) {
-    Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
-    __ LoadHeapObject(result, function);
+  } else if (lookup.IsConstant()) {
+    Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
+    __ LoadObject(result, constant);
   } else {
     // Negative lookup.
     // Check prototypes.
@@ -2722,7 +2717,7 @@ static bool CompactEmit(SmallMapList* list,
   if (map->HasElementsTransition()) return false;
   LookupResult lookup(isolate);
   map->LookupDescriptor(NULL, *name, &lookup);
-  return lookup.IsField() || lookup.IsConstantFunction();
+  return lookup.IsField() || lookup.IsConstant();
 }
 
 
index a903ea1..542018f 100644 (file)
@@ -794,11 +794,9 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   Representation representation = details.representation();
   ASSERT(!representation.IsNone());
 
-  if (details.type() == CONSTANT_FUNCTION) {
-    Handle<HeapObject> constant(
-        HeapObject::cast(descriptors->GetValue(descriptor)));
-    __ LoadHeapObject(scratch1, constant);
-    __ cmpq(value_reg, scratch1);
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
+    __ CmpObject(value_reg, constant);
     __ j(not_equal, miss_label);
   } else if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_label);
@@ -857,7 +855,7 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
                       OMIT_REMEMBERED_SET,
                       OMIT_SMI_CHECK);
 
-  if (details.type() == CONSTANT_FUNCTION) {
+  if (details.type() == CONSTANT) {
     ASSERT(value_reg.is(rax));
     __ ret(0);
     return;
@@ -1357,9 +1355,9 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
 }
 
 
-void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) {
+void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
   // Return the constant value.
-  __ LoadHeapObject(rax, value);
+  __ LoadObject(rax, value);
   __ ret(0);
 }
 
@@ -2500,7 +2498,7 @@ Handle<Code> CallStubCompiler::CompileCallConstant(
     Handle<Code> code = CompileCustomCall(object, holder,
                                           Handle<PropertyCell>::null(),
                                           function, Handle<String>::cast(name),
-                                          Code::CONSTANT_FUNCTION);
+                                          Code::CONSTANT);
     // A null handle means bail out to the regular compiler code below.
     if (!code.is_null()) return code;
   }