Revision: 23083
Author:   [email protected]
Date:     Tue Aug 12 15:28:20 2014 UTC
Log:      Add "own" symbols support.

"Own" symbols are symbols that can only denote own properties of
objects.

[email protected], [email protected]

Committed: https://code.google.com/p/v8/source/detail?r=23056

Review URL: https://codereview.chromium.org/464473002
http://code.google.com/p/v8/source/detail?r=23083

Added:
 /branches/bleeding_edge/test/mjsunit/own-symbols.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/createprivateownsymbol.js
Modified:
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/heap/heap.cc
 /branches/bleeding_edge/src/lookup.h
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects-printer.cc
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/own-symbols.js Tue Aug 12 15:28:20 2014 UTC
@@ -0,0 +1,55 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --allow-natives-syntax
+
+var s = %CreatePrivateOwnSymbol("s");
+var s1 = %CreatePrivateOwnSymbol("s1");
+
+function TestSimple() {
+  var p = {}
+  p[s] = "moo";
+
+  var o = Object.create(p);
+
+  assertEquals(undefined, o[s]);
+  assertEquals("moo", p[s]);
+
+  o[s] = "bow-wow";
+  assertEquals("bow-wow", o[s]);
+  assertEquals("moo", p[s]);
+}
+
+TestSimple();
+
+
+function TestICs() {
+  var p = {}
+  p[s] = "moo";
+
+
+  var o = Object.create(p);
+  o[s1] = "bow-wow";
+  function checkNonOwn(o) {
+    assertEquals(undefined, o[s]);
+    assertEquals("bow-wow", o[s1]);
+  }
+
+  checkNonOwn(o);
+
+  // Test monomorphic/optimized.
+  for (var i = 0; i < 1000; i++) {
+    checkNonOwn(o);
+  }
+
+  // Test non-monomorphic.
+  for (var i = 0; i < 1000; i++) {
+    var oNew = Object.create(p);
+    oNew["s" + i] = i;
+    oNew[s1] = "bow-wow";
+    checkNonOwn(oNew);
+  }
+}
+
+TestICs();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/runtime-gen/createprivateownsymbol.js Tue Aug 12 15:28:20 2014 UTC
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var arg0 = "foo";
+%CreatePrivateOwnSymbol(arg0);
=======================================
--- /branches/bleeding_edge/src/factory.cc      Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc      Tue Aug 12 15:28:20 2014 UTC
@@ -662,6 +662,14 @@
   symbol->set_is_private(true);
   return symbol;
 }
+
+
+Handle<Symbol> Factory::NewPrivateOwnSymbol() {
+  Handle<Symbol> symbol = NewSymbol();
+  symbol->set_is_private(true);
+  symbol->set_is_own(true);
+  return symbol;
+}


 Handle<Context> Factory::NewNativeContext() {
=======================================
--- /branches/bleeding_edge/src/factory.h       Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/factory.h       Tue Aug 12 15:28:20 2014 UTC
@@ -221,6 +221,7 @@
   // Create a symbol.
   Handle<Symbol> NewSymbol();
   Handle<Symbol> NewPrivateSymbol();
+  Handle<Symbol> NewPrivateOwnSymbol();

   // Create a global (but otherwise uninitialized) context.
   Handle<Context> NewNativeContext();
=======================================
--- /branches/bleeding_edge/src/heap/heap.cc    Mon Aug 11 14:22:24 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.cc    Tue Aug 12 15:28:20 2014 UTC
@@ -2834,7 +2834,7 @@

   // Allocate the dictionary of intrinsic function names.
   Handle<NameDictionary> intrinsic_names =
-      NameDictionary::New(isolate(), Runtime::kNumFunctions);
+      NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED);
   Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
   set_intrinsic_function_names(*intrinsic_names);

=======================================
--- /branches/bleeding_edge/src/lookup.h        Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/lookup.h        Tue Aug 12 15:28:20 2014 UTC
@@ -47,7 +47,7 @@
   LookupIterator(Handle<Object> receiver,
                  Handle<Name> name,
                  Configuration configuration = CHECK_ALL)
-      : configuration_(configuration),
+      : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
         property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
@@ -66,7 +66,7 @@
                  Handle<Name> name,
                  Handle<JSReceiver> holder,
                  Configuration configuration = CHECK_ALL)
-      : configuration_(configuration),
+      : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
         property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
@@ -186,6 +186,15 @@
     DCHECK_EQ(DICTIONARY, property_encoding_);
     return number_;
   }
+
+  static Configuration ComputeConfiguration(
+      Configuration configuration, Handle<Name> name) {
+    if (name->IsOwn()) {
+      return static_cast<Configuration>(configuration & CHECK_OWN);
+    } else {
+      return configuration;
+    }
+  }

   Configuration configuration_;
   State state_;
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Tue Aug 12 15:28:20 2014 UTC
@@ -3372,6 +3372,7 @@
 ACCESSORS(Symbol, name, Object, kNameOffset)
 ACCESSORS(Symbol, flags, Smi, kFlagsOffset)
 BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
+BOOL_ACCESSORS(Symbol, flags, is_own, kOwnBit)


 bool String::Equals(String* other) {
@@ -6495,6 +6496,10 @@
   // Slow case: compute hash code and set it. Has to be a string.
   return String::cast(this)->ComputeAndSetHash();
 }
+
+bool Name::IsOwn() {
+  return this->IsSymbol() && Symbol::cast(this)->is_own();
+}


 StringHasher::StringHasher(int length, uint32_t seed)
=======================================
--- /branches/bleeding_edge/src/objects-printer.cc Mon Aug 11 21:44:08 2014 UTC +++ /branches/bleeding_edge/src/objects-printer.cc Tue Aug 12 15:28:20 2014 UTC
@@ -430,7 +430,8 @@
   HeapObject::PrintHeader(os, "Symbol");
   os << " - hash: " << Hash();
   os << "\n - name: " << Brief(name());
-  os << " - private: " << is_private();
+  os << "\n - private: " << is_private();
+  os << "\n - own: " << is_own();
   os << "\n";
 }

=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Tue Aug 12 15:28:20 2014 UTC
@@ -3560,6 +3560,11 @@

 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name,
                                                    LookupResult* result) {
+  if (name->IsOwn()) {
+    result->NotFound();
+    return;
+  }
+
   DisallowHeapAllocation no_gc;
   Isolate* isolate = GetIsolate();
for (PrototypeIterator iter(isolate, this); !iter.IsAtEnd(); iter.Advance()) {
@@ -6107,7 +6112,7 @@
   }

   js_object->LookupOwnRealNamedProperty(name, result);
-  if (result->IsFound() || !search_hidden_prototypes) return;
+ if (result->IsFound() || name->IsOwn() || !search_hidden_prototypes) return;

   PrototypeIterator iter(GetIsolate(), js_object);
   if (!iter.GetCurrent()->IsJSReceiver()) return;
@@ -6126,6 +6131,10 @@
        !iter.IsAtEnd(); iter.Advance()) {
     JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result, false);
     if (result->IsFound()) return;
+    if (name->IsOwn()) {
+      result->NotFound();
+      return;
+    }
   }
   result->NotFound();
 }
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Aug 11 22:17:19 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Tue Aug 12 15:28:20 2014 UTC
@@ -8954,6 +8954,9 @@
   // Conversion.
   inline bool AsArrayIndex(uint32_t* index);

+  // Whether name can only name own properties.
+  inline bool IsOwn();
+
   DECLARE_CAST(Name)

   DECLARE_PRINTER(Name)
@@ -9029,6 +9032,10 @@
   // [is_private]: whether this is a private symbol.
   DECL_BOOLEAN_ACCESSORS(is_private)

+ // [is_own]: whether this is an own symbol, that is, only used to designate
+  // own properties of objects.
+  DECL_BOOLEAN_ACCESSORS(is_own)
+
   DECLARE_CAST(Symbol)

   // Dispatched behavior.
@@ -9044,6 +9051,7 @@

  private:
   static const int kPrivateBit = 0;
+  static const int kOwnBit = 1;

   DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
 };
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Tue Aug 12 15:28:20 2014 UTC
@@ -606,6 +606,17 @@
   if (name->IsString()) symbol->set_name(*name);
   return *symbol;
 }
+
+
+RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+  Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
+  if (name->IsString()) symbol->set_name(*name);
+  return *symbol;
+}


 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Mon Aug 11 21:44:08 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Tue Aug 12 15:28:20 2014 UTC
@@ -260,6 +260,7 @@
   F(CreateSymbol, 1, 1)                                               \
   F(CreatePrivateSymbol, 1, 1)                                        \
   F(CreateGlobalPrivateSymbol, 1, 1)                                  \
+  F(CreatePrivateOwnSymbol, 1, 1)                                     \
   F(NewSymbolWrapper, 1, 1)                                           \
   F(SymbolDescription, 1, 1)                                          \
   F(SymbolRegistry, 0, 1)                                             \
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Tue Aug 12 13:36:33 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Tue Aug 12 15:28:20 2014 UTC
@@ -47,8 +47,8 @@
# that the parser doesn't bit-rot. Change the values as needed when you add, # remove or change runtime functions, but make sure we don't lose our ability
 # to parse them!
-EXPECTED_FUNCTION_COUNT = 428
-EXPECTED_FUZZABLE_COUNT = 331
+EXPECTED_FUNCTION_COUNT = 429
+EXPECTED_FUZZABLE_COUNT = 332
 EXPECTED_CCTEST_COUNT = 7
 EXPECTED_UNKNOWN_COUNT = 16
 EXPECTED_BUILTINS_COUNT = 808
@@ -226,6 +226,7 @@
   "CreateBreakIterator": ["'en-US'", "{type: 'string'}", None, None],
   "CreateJSFunctionProxy": [None, "function() {}", None, None, None],
   "CreatePrivateSymbol": ["\"foo\"", None],
+  "CreatePrivateOwnSymbol": ["\"foo\"", None],
   "CreateSymbol": ["\"foo\"", None],
   "DateParseString": [None, "new Array(8)", None],
   "DefineAccessorPropertyUnchecked": [None, None, "function() {}",

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to