summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime.cc')
-rw-r--r--deps/v8/src/runtime.cc914
1 files changed, 447 insertions, 467 deletions
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 3e04942933..3ea93049c0 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -42,7 +42,6 @@
#include "deoptimizer.h"
#include "execution.h"
#include "global-handles.h"
-#include "isolate-inl.h"
#include "jsregexp.h"
#include "json-parser.h"
#include "liveedit.h"
@@ -178,7 +177,6 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
// Pixel elements cannot be created using an object literal.
ASSERT(!copy->HasExternalArrayElements());
switch (copy->GetElementsKind()) {
- case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
FixedArray* elements = FixedArray::cast(copy->elements());
if (elements->map() == heap->fixed_cow_array_map()) {
@@ -191,9 +189,6 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
} else {
for (int i = 0; i < elements->length(); i++) {
Object* value = elements->get(i);
- ASSERT(value->IsSmi() ||
- value->IsTheHole() ||
- (copy->GetElementsKind() == FAST_ELEMENTS));
if (value->IsJSObject()) {
JSObject* js_object = JSObject::cast(value);
{ MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
@@ -422,9 +417,6 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
}
-static const int kSmiOnlyLiteralMinimumLength = 1024;
-
-
static Handle<Object> CreateArrayLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
@@ -434,38 +426,22 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
JSFunction::GlobalContextFromLiterals(*literals)->array_function());
Handle<Object> object = isolate->factory()->NewJSObject(constructor);
- if (elements->length() > kSmiOnlyLiteralMinimumLength) {
- Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap(
- Handle<JSObject>::cast(object),
- FAST_SMI_ONLY_ELEMENTS);
- HeapObject::cast(*object)->set_map(*smi_array_map);
- }
-
const bool is_cow =
(elements->map() == isolate->heap()->fixed_cow_array_map());
Handle<FixedArray> copied_elements =
is_cow ? elements : isolate->factory()->CopyFixedArray(elements);
Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
- bool has_non_smi = false;
if (is_cow) {
+#ifdef DEBUG
// Copy-on-write arrays must be shallow (and simple).
for (int i = 0; i < content->length(); i++) {
- Object* current = content->get(i);
- ASSERT(!current->IsFixedArray());
- if (!current->IsSmi() && !current->IsTheHole()) {
- has_non_smi = true;
- }
- }
-#if DEBUG
- for (int i = 0; i < content->length(); i++) {
ASSERT(!content->get(i)->IsFixedArray());
}
#endif
} else {
for (int i = 0; i < content->length(); i++) {
- Object* current = content->get(i);
- if (current->IsFixedArray()) {
+ if (content->get(i)->IsFixedArray()) {
// The value contains the constant_properties of a
// simple object or array literal.
Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
@@ -473,23 +449,12 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
CreateLiteralBoilerplate(isolate, literals, fa);
if (result.is_null()) return result;
content->set(i, *result);
- has_non_smi = true;
- } else {
- if (!current->IsSmi() && !current->IsTheHole()) {
- has_non_smi = true;
- }
}
}
}
// Set the elements.
- Handle<JSArray> js_object(Handle<JSArray>::cast(object));
- isolate->factory()->SetContent(js_object, content);
-
- if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
- isolate->factory()->EnsureCanContainNonSmiElements(js_object);
- }
-
+ Handle<JSArray>::cast(object)->SetContent(*content);
return object;
}
@@ -720,8 +685,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
- CONVERT_ARG_CHECKED(JSReceiver, key, 1);
- return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
+ // TODO(mstarzinger): Currently we cannot use JSProxy objects as keys
+ // because they cannot be cast to JSObject to get an identity hash code.
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
+ return weakmap->table()->Lookup(*key);
}
@@ -729,9 +696,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
- CONVERT_ARG_CHECKED(JSReceiver, key, 1);
+ // TODO(mstarzinger): See Runtime_WeakMapGet above.
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
Handle<Object> value(args[2]);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<ObjectHashTable> table(weakmap->table());
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
weakmap->set_table(*new_table);
return *value;
@@ -1243,17 +1211,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
LookupResult lookup;
global->Lookup(*name, &lookup);
if (lookup.IsProperty()) {
- // We found an existing property. Unless it was an interceptor
- // that claims the property is absent, skip this declaration.
- if (lookup.type() != INTERCEPTOR) {
- continue;
- }
+ // Determine if the property is local by comparing the holder
+ // against the global object. The information will be used to
+ // avoid throwing re-declaration errors when declaring
+ // variables or constants that exist in the prototype chain.
+ bool is_local = (*global == lookup.holder());
+ // Get the property attributes and determine if the property is
+ // read-only.
PropertyAttributes attributes = global->GetPropertyAttribute(*name);
- if (attributes != ABSENT) {
+ bool is_read_only = (attributes & READ_ONLY) != 0;
+ if (lookup.type() == INTERCEPTOR) {
+ // If the interceptor says the property is there, we
+ // just return undefined without overwriting the property.
+ // Otherwise, we continue to setting the property.
+ if (attributes != ABSENT) {
+ // Check if the existing property conflicts with regards to const.
+ if (is_local && (is_read_only || is_const_property)) {
+ const char* type = (is_read_only) ? "const" : "var";
+ return ThrowRedeclarationError(isolate, type, name);
+ };
+ // The property already exists without conflicting: Go to
+ // the next declaration.
+ continue;
+ }
+ // Fall-through and introduce the absent property by using
+ // SetProperty.
+ } else {
+ // For const properties, we treat a callback with this name
+ // even in the prototype as a conflicting declaration.
+ if (is_const_property && (lookup.type() == CALLBACKS)) {
+ return ThrowRedeclarationError(isolate, "const", name);
+ }
+ // Otherwise, we check for locally conflicting declarations.
+ if (is_local && (is_read_only || is_const_property)) {
+ const char* type = (is_read_only) ? "const" : "var";
+ return ThrowRedeclarationError(isolate, type, name);
+ }
+ // The property already exists without conflicting: Go to
+ // the next declaration.
continue;
}
- // Fall-through and introduce the absent property by using
- // SetProperty.
}
} else {
is_function_declaration = true;
@@ -1270,6 +1267,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
LookupResult lookup;
global->LocalLookup(*name, &lookup);
+ // There's a local property that we need to overwrite because
+ // we're either declaring a function or there's an interceptor
+ // that claims the property is absent.
+ //
+ // Check for conflicting re-declarations. We cannot have
+ // conflicting types in case of intercepted properties because
+ // they are absent.
+ if (lookup.IsProperty() &&
+ (lookup.type() != INTERCEPTOR) &&
+ (lookup.IsReadOnly() || is_const_property)) {
+ const char* type = (lookup.IsReadOnly()) ? "const" : "var";
+ return ThrowRedeclarationError(isolate, type, name);
+ }
+
// Compute the property attributes. According to ECMA-262, section
// 13, page 71, the property must be read-only and
// non-deletable. However, neither SpiderMonkey nor KJS creates the
@@ -1324,17 +1335,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- // Declarations are always made in a function or global context. In the
- // case of eval code, the context passed is the context of the caller,
- // which may be some nested context and not the declaration context.
- RUNTIME_ASSERT(args[0]->IsContext());
- Handle<Context> context(Context::cast(args[0])->declaration_context());
-
+ CONVERT_ARG_CHECKED(Context, context, 0);
Handle<String> name(String::cast(args[1]));
PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
Handle<Object> initial_value(args[3], isolate);
+ // Declarations are always done in a function or global context.
+ context = Handle<Context>(context->declaration_context());
+
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
@@ -1343,7 +1352,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
context->Lookup(name, flags, &index, &attributes, &binding_flags);
if (attributes != ABSENT) {
- // The name was declared before; check for conflicting re-declarations.
+ // The name was declared before; check for conflicting
+ // re-declarations: This is similar to the code in parser.cc in
+ // the AstBuildingParser::Declare function.
if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
// Functions are not read-only.
ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
@@ -1354,41 +1365,53 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
// Initialize it if necessary.
if (*initial_value != NULL) {
if (index >= 0) {
- ASSERT(holder.is_identical_to(context));
- if (((attributes & READ_ONLY) == 0) ||
- context->get(index)->IsTheHole()) {
- context->set(index, *initial_value);
+ // The variable or constant context slot should always be in
+ // the function context or the arguments object.
+ if (holder->IsContext()) {
+ ASSERT(holder.is_identical_to(context));
+ if (((attributes & READ_ONLY) == 0) ||
+ context->get(index)->IsTheHole()) {
+ context->set(index, *initial_value);
+ }
+ } else {
+ // The holder is an arguments object.
+ Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
+ Handle<Object> result = SetElement(arguments, index, initial_value,
+ kNonStrictMode);
+ if (result.is_null()) return Failure::Exception();
}
} else {
- // Slow case: The property is in the context extension object of a
- // function context or the global object of a global context.
- Handle<JSObject> object = Handle<JSObject>::cast(holder);
+ // Slow case: The property is not in the FixedArray part of the context.
+ Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, initial_value, mode, kNonStrictMode));
+ SetProperty(context_ext, name, initial_value,
+ mode, kNonStrictMode));
}
}
} else {
// The property is not in the function context. It needs to be
- // "declared" in the function context's extension context or as a
- // property of the the global object.
- Handle<JSObject> object;
+ // "declared" in the function context's extension context, or in the
+ // global context.
+ Handle<JSObject> context_ext;
if (context->has_extension()) {
- object = Handle<JSObject>(JSObject::cast(context->extension()));
+ // The function context's extension context exists - use it.
+ context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
} else {
- // Context extension objects are allocated lazily.
- ASSERT(context->IsFunctionContext());
- object = isolate->factory()->NewJSObject(
+ // The function context's extension context does not exists - allocate
+ // it.
+ context_ext = isolate->factory()->NewJSObject(
isolate->context_extension_function());
- context->set_extension(*object);
+ // And store it in the extension slot.
+ context->set_extension(*context_ext);
}
- ASSERT(*object != NULL);
+ ASSERT(*context_ext != NULL);
// Declare the property by setting it to the initial value if provided,
// or undefined, and use the correct mode (e.g. READ_ONLY attribute for
// constant declarations).
- ASSERT(!object->HasLocalProperty(*name));
+ ASSERT(!context_ext->HasLocalProperty(*name));
Handle<Object> value(isolate->heap()->undefined_value(), isolate);
if (*initial_value != NULL) value = initial_value;
// Declaring a const context slot is a conflicting declaration if
@@ -1398,15 +1421,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
// SetProperty and no setters are invoked for those since they are
// not real JSObjects.
if (initial_value->IsTheHole() &&
- !object->IsJSContextExtensionObject()) {
+ !context_ext->IsJSContextExtensionObject()) {
LookupResult lookup;
- object->Lookup(*name, &lookup);
+ context_ext->Lookup(*name, &lookup);
if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
return ThrowRedeclarationError(isolate, "const", name);
}
}
RETURN_IF_EMPTY_HANDLE(isolate,
- SetProperty(object, name, value, mode,
+ SetProperty(context_ext, name, value, mode,
kNonStrictMode));
}
@@ -1442,32 +1465,64 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
// to assign to the property.
// Note that objects can have hidden prototypes, so we need to traverse
// the whole chain of hidden prototypes to do a 'local' lookup.
- Object* object = global;
+ JSObject* real_holder = global;
LookupResult lookup;
- while (object->IsJSObject() &&
- JSObject::cast(object)->map()->is_hidden_prototype()) {
- JSObject* raw_holder = JSObject::cast(object);
- raw_holder->LocalLookup(*name, &lookup);
- if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
- HandleScope handle_scope(isolate);
- Handle<JSObject> holder(raw_holder);
- PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
- // Update the raw pointer in case it's changed due to GC.
- raw_holder = *holder;
- if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
- // Found an interceptor that's not read only.
- if (assign) {
- return raw_holder->SetProperty(
- &lookup, *name, args[2], attributes, strict_mode);
- } else {
- return isolate->heap()->undefined_value();
+ while (true) {
+ real_holder->LocalLookup(*name, &lookup);
+ if (lookup.IsProperty()) {
+ // Determine if this is a redeclaration of something read-only.
+ if (lookup.IsReadOnly()) {
+ // If we found readonly property on one of hidden prototypes,
+ // just shadow it.
+ if (real_holder != isolate->context()->global()) break;
+ return ThrowRedeclarationError(isolate, "const", name);
+ }
+
+ // Determine if this is a redeclaration of an intercepted read-only
+ // property and figure out if the property exists at all.
+ bool found = true;
+ PropertyType type = lookup.type();
+ if (type == INTERCEPTOR) {
+ HandleScope handle_scope(isolate);
+ Handle<JSObject> holder(real_holder);
+ PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
+ real_holder = *holder;
+ if (intercepted == ABSENT) {
+ // The interceptor claims the property isn't there. We need to
+ // make sure to introduce it.
+ found = false;
+ } else if ((intercepted & READ_ONLY) != 0) {
+ // The property is present, but read-only. Since we're trying to
+ // overwrite it with a variable declaration we must throw a
+ // re-declaration error. However if we found readonly property
+ // on one of hidden prototypes, just shadow it.
+ if (real_holder != isolate->context()->global()) break;
+ return ThrowRedeclarationError(isolate, "const", name);
}
}
+
+ if (found && !assign) {
+ // The global property is there and we're not assigning any value
+ // to it. Just return.
+ return isolate->heap()->undefined_value();
+ }
+
+ // Assign the value (or undefined) to the property.
+ Object* value = (assign) ? args[2] : isolate->heap()->undefined_value();
+ return real_holder->SetProperty(
+ &lookup, *name, value, attributes, strict_mode);
}
- object = raw_holder->GetPrototype();
+
+ Object* proto = real_holder->GetPrototype();
+ if (!proto->IsJSObject())
+ break;
+
+ if (!JSObject::cast(proto)->map()->is_hidden_prototype())
+ break;
+
+ real_holder = JSObject::cast(proto);
}
- // Reload global in case the loop above performed a GC.
global = isolate->context()->global();
if (assign) {
return global->SetProperty(*name, args[2], attributes, strict_mode);
@@ -1505,9 +1560,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
attributes);
}
+ // Determine if this is a redeclaration of something not
+ // read-only. In case the result is hidden behind an interceptor we
+ // need to ask it for the property attributes.
if (!lookup.IsReadOnly()) {
+ if (lookup.type() != INTERCEPTOR) {
+ return ThrowRedeclarationError(isolate, "var", name);
+ }
+
+ PropertyAttributes intercepted = global->GetPropertyAttribute(*name);
+
+ // Throw re-declaration error if the intercepted property is present
+ // but not read-only.
+ if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
+ return ThrowRedeclarationError(isolate, "var", name);
+ }
+
// Restore global object from context (in case of GC) and continue
- // with setting the value.
+ // with setting the value because the property is either absent or
+ // read-only. We also have to do redo the lookup.
HandleScope handle_scope(isolate);
Handle<GlobalObject> global(isolate->context()->global());
@@ -1524,20 +1595,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
return *value;
}
- // Set the value, but only if we're assigning the initial value to a
+ // Set the value, but only we're assigning the initial value to a
// constant. For now, we determine this by checking if the
// current value is the hole.
- // Strict mode handling not needed (const is disallowed in strict mode).
+ // Strict mode handling not needed (const disallowed in strict mode).
PropertyType type = lookup.type();
if (type == FIELD) {
FixedArray* properties = global->properties();
int index = lookup.GetFieldIndex();
- if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
+ if (properties->get(index)->IsTheHole()) {
properties->set(index, *value);
}
} else if (type == NORMAL) {
- if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
- !lookup.IsReadOnly()) {
+ if (global->GetNormalizedProperty(&lookup)->IsTheHole()) {
global->SetNormalizedProperty(&lookup, *value);
}
} else {
@@ -1557,12 +1627,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
Handle<Object> value(args[0], isolate);
ASSERT(!value->IsTheHole());
+ CONVERT_ARG_CHECKED(Context, context, 1);
+ Handle<String> name(String::cast(args[2]));
// Initializations are always done in a function or global context.
- RUNTIME_ASSERT(args[1]->IsContext());
- Handle<Context> context(Context::cast(args[1])->declaration_context());
-
- Handle<String> name(String::cast(args[2]));
+ context = Handle<Context>(context->declaration_context());
int index;
PropertyAttributes attributes;
@@ -1571,19 +1640,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes, &binding_flags);
+ // In most situations, the property introduced by the const
+ // declaration should be present in the context extension object.
+ // However, because declaration and initialization are separate, the
+ // property might have been deleted (if it was introduced by eval)
+ // before we reach the initialization point.
+ //
+ // Example:
+ //
+ // function f() { eval("delete x; const x;"); }
+ //
+ // In that case, the initialization behaves like a normal assignment
+ // to property 'x'.
if (index >= 0) {
- ASSERT(holder->IsContext());
- // Property was found in a context. Perform the assignment if we
- // found some non-constant or an uninitialized constant.
- Handle<Context> context = Handle<Context>::cast(holder);
- if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
- context->set(index, *value);
+ if (holder->IsContext()) {
+ // Property was found in a context. Perform the assignment if we
+ // found some non-constant or an uninitialized constant.
+ Handle<Context> context = Handle<Context>::cast(holder);
+ if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
+ context->set(index, *value);
+ }
+ } else {
+ // The holder is an arguments object.
+ ASSERT((attributes & READ_ONLY) == 0);
+ Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ SetElement(arguments, index, value, kNonStrictMode));
}
return *value;
}
- // The property could not be found, we introduce it as a property of the
- // global object.
+ // The property could not be found, we introduce it in the global
+ // context.
if (attributes == ABSENT) {
Handle<JSObject> global = Handle<JSObject>(
isolate->context()->global());
@@ -1594,41 +1683,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
return *value;
}
- // The property was present in some function's context extension object,
- // as a property on the subject of a with, or as a property of the global
- // object.
- //
- // In most situations, eval-introduced consts should still be present in
- // the context extension object. However, because declaration and
- // initialization are separate, the property might have been deleted
- // before we reach the initialization point.
- //
- // Example:
- //
- // function f() { eval("delete x; const x;"); }
- //
- // In that case, the initialization behaves like a normal assignment.
- Handle<JSObject> object = Handle<JSObject>::cast(holder);
+ // The property was present in a context extension object.
+ Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
- if (*object == context->extension()) {
- // This is the property that was introduced by the const declaration.
- // Set it if it hasn't been set before. NOTE: We cannot use
- // GetProperty() to get the current value as it 'unholes' the value.
+ if (*context_ext == context->extension()) {
+ // This is the property that was introduced by the const
+ // declaration. Set it if it hasn't been set before. NOTE: We
+ // cannot use GetProperty() to get the current value as it
+ // 'unholes' the value.
LookupResult lookup;
- object->LocalLookupRealNamedProperty(*name, &lookup);
+ context_ext->LocalLookupRealNamedProperty(*name, &lookup);
ASSERT(lookup.IsProperty()); // the property was declared
ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
PropertyType type = lookup.type();
if (type == FIELD) {
- FixedArray* properties = object->properties();
+ FixedArray* properties = context_ext->properties();
int index = lookup.GetFieldIndex();
if (properties->get(index)->IsTheHole()) {
properties->set(index, *value);
}
} else if (type == NORMAL) {
- if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
- object->SetNormalizedProperty(&lookup, *value);
+ if (context_ext->GetNormalizedProperty(&lookup)->IsTheHole()) {
+ context_ext->SetNormalizedProperty(&lookup, *value);
}
} else {
// We should not reach here. Any real, named property should be
@@ -1636,13 +1713,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
UNREACHABLE();
}
} else {
- // The property was found on some other object. Set it if it is not a
- // read-only property.
+ // The property was found in a different context extension object.
+ // Set it if it is not a read-only property.
if ((attributes & READ_ONLY) == 0) {
// Strict mode not needed (const disallowed in strict mode).
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, value, attributes, kNonStrictMode));
+ SetProperty(context_ext, name, value, attributes, kNonStrictMode));
}
}
@@ -1663,19 +1740,6 @@ RUNTIME_FUNCTION(MaybeObject*,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, object, 0);
- if (object->HasFastSmiOnlyElements()) {
- MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
- Map* map;
- if (!maybe_map->To<Map>(&map)) return maybe_map;
- object->set_map(Map::cast(map));
- }
- return *object;
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
@@ -1761,7 +1825,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline);
regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0),
- SKIP_WRITE_BARRIER); // It's a Smi.
+ SKIP_WRITE_BARRIER);
return regexp;
}
@@ -2175,7 +2239,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
literals->set(JSFunction::kLiteralGlobalContextIndex,
context->global_context());
}
- target->set_literals(*literals);
+ // It's okay to skip the write barrier here because the literals
+ // are guaranteed to be in old space.
+ target->set_literals(*literals, SKIP_WRITE_BARRIER);
target->set_next_function_link(isolate->heap()->undefined_value());
if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
@@ -2259,8 +2325,7 @@ class FixedArrayBuilder {
public:
explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
: array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
- length_(0),
- has_non_smi_elements_(false) {
+ length_(0) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
ASSERT(initial_capacity > 0);
@@ -2268,8 +2333,7 @@ class FixedArrayBuilder {
explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
: array_(backing_store),
- length_(0),
- has_non_smi_elements_(false) {
+ length_(0) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
ASSERT(backing_store->length() > 0);
@@ -2297,15 +2361,12 @@ class FixedArrayBuilder {
}
void Add(Object* value) {
- ASSERT(!value->IsSmi());
ASSERT(length_ < capacity());
array_->set(length_, value);
length_++;
- has_non_smi_elements_ = true;
}
void Add(Smi* value) {
- ASSERT(value->IsSmi());
ASSERT(length_ < capacity());
array_->set(length_, value);
length_++;
@@ -2330,7 +2391,7 @@ class FixedArrayBuilder {
}
Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
- FACTORY->SetContent(target_array, array_);
+ target_array->set_elements(*array_);
target_array->set_length(Smi::FromInt(length_));
return target_array;
}
@@ -2338,7 +2399,6 @@ class FixedArrayBuilder {
private:
Handle<FixedArray> array_;
int length_;
- bool has_non_smi_elements_;
};
@@ -2833,7 +2893,7 @@ void FindStringIndicesDispatch(Isolate* isolate,
}
} else {
Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
- if (pattern_content.IsAscii()) {
+ if (pattern->IsAsciiRepresentation()) {
FindStringIndices(isolate,
subject_vector,
pattern_content.ToAsciiVector(),
@@ -2959,7 +3019,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
// Shortcut for simple non-regexp global replacements
if (is_global &&
- regexp_handle->TypeTag() == JSRegExp::ATOM &&
+ regexp->TypeTag() == JSRegExp::ATOM &&
compiled_replacement.simple_hint()) {
if (subject_handle->HasOnlyAsciiChars() &&
replacement_handle->HasOnlyAsciiChars()) {
@@ -3182,9 +3242,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
Address end_of_string = answer->address() + string_size;
isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
- if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
- MemoryChunk::IncrementLiveBytes(answer->address(), -delta);
- }
return *answer;
}
@@ -3944,13 +4001,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
// Slow case.
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
if (isnan(value)) {
- return *isolate->factory()->nan_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
}
if (isinf(value)) {
if (value < 0) {
- return *isolate->factory()->minus_infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
}
- return *isolate->factory()->infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
}
char* str = DoubleToRadixCString(value, radix);
MaybeObject* result =
@@ -3966,13 +4023,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
if (isnan(value)) {
- return *isolate->factory()->nan_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
}
if (isinf(value)) {
if (value < 0) {
- return *isolate->factory()->minus_infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
}
- return *isolate->factory()->infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
@@ -3991,13 +4048,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
if (isnan(value)) {
- return *isolate->factory()->nan_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
}
if (isinf(value)) {
if (value < 0) {
- return *isolate->factory()->minus_infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
}
- return *isolate->factory()->infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
@@ -4016,13 +4073,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
if (isnan(value)) {
- return *isolate->factory()->nan_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
}
if (isinf(value)) {
if (value < 0) {
- return *isolate->factory()->minus_infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
}
- return *isolate->factory()->infinity_symbol();
+ return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
@@ -4212,7 +4269,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
CONVERT_CHECKED(String, name, args[1]);
CONVERT_CHECKED(Smi, flag_setter, args[2]);
Object* fun = args[3];
- RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined());
+ RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined());
CONVERT_CHECKED(Smi, flag_attr, args[4]);
int unchecked = flag_attr->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
@@ -4380,14 +4437,6 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
return isolate->Throw(*error);
}
- if (object->IsJSProxy()) {
- bool has_pending_exception = false;
- Handle<Object> name = Execution::ToString(key, &has_pending_exception);
- if (has_pending_exception) return Failure::Exception();
- return JSProxy::cast(*object)->SetProperty(
- String::cast(*name), *value, attr, strict_mode);
- }
-
// If the object isn't a JavaScript object, we ignore the store.
if (!object->IsJSObject()) return *value;
@@ -4507,7 +4556,7 @@ MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
// Check if the given key is an array index.
uint32_t index;
- if (key->ToArrayIndex(&index)) {
+ if (receiver->IsJSObject() && key->ToArrayIndex(&index)) {
// In Firefox/SpiderMonkey, Safari and Opera you can access the
// characters of a string using [] notation. In the case of a
// String object we just need to redirect the deletion to the
@@ -4518,7 +4567,8 @@ MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
return isolate->heap()->true_value();
}
- return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION);
+ return JSObject::cast(*receiver)->DeleteElement(
+ index, JSReceiver::FORCE_DELETION);
}
Handle<String> key_string;
@@ -4680,24 +4730,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
NoHandleAllocation na;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSReceiver, receiver, args[0]);
- CONVERT_CHECKED(String, key, args[1]);
- bool result = receiver->HasProperty(key);
- if (isolate->has_pending_exception()) return Failure::Exception();
- return isolate->heap()->ToBoolean(result);
+ // Only JS receivers can have properties.
+ if (args[0]->IsJSReceiver()) {
+ JSReceiver* receiver = JSReceiver::cast(args[0]);
+ CONVERT_CHECKED(String, key, args[1]);
+ if (receiver->HasProperty(key)) return isolate->heap()->true_value();
+ }
+ return isolate->heap()->false_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
NoHandleAllocation na;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSReceiver, receiver, args[0]);
- CONVERT_CHECKED(Smi, index, args[1]);
- bool result = receiver->HasElement(index->value());
- if (isolate->has_pending_exception()) return Failure::Exception();
- return isolate->heap()->ToBoolean(result);
+ // Only JS objects can have elements.
+ if (args[0]->IsJSObject()) {
+ JSObject* object = JSObject::cast(args[0]);
+ CONVERT_CHECKED(Smi, index_obj, args[1]);
+ uint32_t index = index_obj->value();
+ if (object->HasElement(index)) return isolate->heap()->true_value();
+ }
+ return isolate->heap()->false_value();
}
@@ -4710,37 +4765,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
uint32_t index;
if (key->AsArrayIndex(&index)) {
- JSObject::LocalElementType type = object->HasLocalElement(index);
- switch (type) {
- case JSObject::UNDEFINED_ELEMENT:
- case JSObject::STRING_CHARACTER_ELEMENT:
- return isolate->heap()->false_value();
- case JSObject::INTERCEPTED_ELEMENT:
- case JSObject::FAST_ELEMENT:
- return isolate->heap()->true_value();
- case JSObject::DICTIONARY_ELEMENT: {
- if (object->IsJSGlobalProxy()) {
- Object* proto = object->GetPrototype();
- if (proto->IsNull()) {
- return isolate->heap()->false_value();
- }
- ASSERT(proto->IsJSGlobalObject());
- object = JSObject::cast(proto);
- }
- FixedArray* elements = FixedArray::cast(object->elements());
- NumberDictionary* dictionary = NULL;
- if (elements->map() ==
- isolate->heap()->non_strict_arguments_elements_map()) {
- dictionary = NumberDictionary::cast(elements->get(1));
- } else {
- dictionary = NumberDictionary::cast(elements);
- }
- int entry = dictionary->FindEntry(index);
- ASSERT(entry != NumberDictionary::kNotFound);
- PropertyDetails details = dictionary->DetailsAt(entry);
- return isolate->heap()->ToBoolean(!details.IsDontEnum());
- }
- }
+ return isolate->heap()->ToBoolean(object->HasElement(index));
}
PropertyAttributes att = object->GetLocalPropertyAttribute(key);
@@ -5554,7 +5579,7 @@ static MaybeObject* SlowQuoteJsonString(Isolate* isolate,
StringType* new_string = StringType::cast(new_object);
Char* write_cursor = reinterpret_cast<Char*>(
- new_string->address() + SeqString::kHeaderSize);
+ new_string->address() + SeqAsciiString::kHeaderSize);
if (comma) *(write_cursor++) = ',';
*(write_cursor++) = '"';
@@ -5642,15 +5667,16 @@ static MaybeObject* QuoteJsonString(Isolate* isolate,
StringType* new_string = StringType::cast(new_object);
ASSERT(isolate->heap()->new_space()->Contains(new_string));
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
Char* write_cursor = reinterpret_cast<Char*>(
- new_string->address() + SeqString::kHeaderSize);
+ new_string->address() + SeqAsciiString::kHeaderSize);
if (comma) *(write_cursor++) = ',';
write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
write_cursor,
characters);
int final_length = static_cast<int>(
write_cursor - reinterpret_cast<Char*>(
- new_string->address() + SeqString::kHeaderSize));
+ new_string->address() + SeqAsciiString::kHeaderSize));
isolate->heap()->new_space()->
template ShrinkStringAtAllocationBoundary<StringType>(
new_string, final_length);
@@ -5728,8 +5754,9 @@ static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
StringType* new_string = StringType::cast(new_object);
ASSERT(isolate->heap()->new_space()->Contains(new_string));
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
Char* write_cursor = reinterpret_cast<Char*>(
- new_string->address() + SeqString::kHeaderSize);
+ new_string->address() + SeqAsciiString::kHeaderSize);
*(write_cursor++) = '[';
for (int i = 0; i < length; i++) {
if (i != 0) *(write_cursor++) = ',';
@@ -5750,7 +5777,7 @@ static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
int final_length = static_cast<int>(
write_cursor - reinterpret_cast<Char*>(
- new_string->address() + SeqString::kHeaderSize));
+ new_string->address() + SeqAsciiString::kHeaderSize));
isolate->heap()->new_space()->
template ShrinkStringAtAllocationBoundary<StringType>(
new_string, final_length);
@@ -6119,7 +6146,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
- return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
+ return unibrow::WhiteSpace::Is(c) || c == 0x200b;
}
@@ -6202,8 +6229,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
int part_count = indices.length();
Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
- MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements();
- if (maybe_result->IsFailure()) return maybe_result;
result->set_length(Smi::FromInt(part_count));
ASSERT(result->HasFastElements());
@@ -6250,11 +6275,11 @@ static int CopyCachedAsciiCharsToArray(Heap* heap,
FixedArray* ascii_cache = heap->single_character_string_cache();
Object* undefined = heap->undefined_value();
int i;
- WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
for (i = 0; i < length; ++i) {
Object* value = ascii_cache->get(chars[i]);
if (value == undefined) break;
- elements->set(i, value, mode);
+ ASSERT(!heap->InNewSpace(value));
+ elements->set(i, value, SKIP_WRITE_BARRIER);
}
if (i < length) {
ASSERT(Smi::FromInt(0) == 0);
@@ -6578,9 +6603,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
// This assumption is used by the slice encoding in one or two smis.
ASSERT(Smi::kMaxValue >= String::kMaxLength);
- MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements();
- if (maybe_result->IsFailure()) return maybe_result;
-
int special_length = special->length();
if (!array->HasFastElements()) {
return isolate->Throw(isolate->heap()->illegal_argument_symbol());
@@ -6808,8 +6830,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
CONVERT_CHECKED(JSArray, elements_array, args[0]);
- RUNTIME_ASSERT(elements_array->HasFastElements() ||
- elements_array->HasFastSmiOnlyElements());
+ RUNTIME_ASSERT(elements_array->HasFastElements());
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
CONVERT_CHECKED(String, separator, args[2]);
// elements_array is fast-mode JSarray of alternating positions
@@ -7926,9 +7947,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
}
-static SmartArrayPointer<Handle<Object> > GetNonBoundArguments(
- int bound_argc,
- int* total_argc) {
+static SmartArrayPointer<Object**> GetNonBoundArguments(int bound_argc,
+ int* total_argc) {
// Find frame containing arguments passed to the caller.
JavaScriptFrameIterator it;
JavaScriptFrame* frame = it.frame();
@@ -7944,11 +7964,10 @@ static SmartArrayPointer<Handle<Object> > GetNonBoundArguments(
&args_slots);
*total_argc = bound_argc + args_count;
- SmartArrayPointer<Handle<Object> > param_data(
- NewArray<Handle<Object> >(*total_argc));
+ SmartArrayPointer<Object**> param_data(NewArray<Object**>(*total_argc));
for (int i = 0; i < args_count; i++) {
Handle<Object> val = args_slots[i].GetValue();
- param_data[bound_argc + i] = val;
+ param_data[bound_argc + i] = val.location();
}
return param_data;
} else {
@@ -7957,11 +7976,10 @@ static SmartArrayPointer<Handle<Object> > GetNonBoundArguments(
int args_count = frame->ComputeParametersCount();
*total_argc = bound_argc + args_count;
- SmartArrayPointer<Handle<Object> > param_data(
- NewArray<Handle<Object> >(*total_argc));
+ SmartArrayPointer<Object**> param_data(NewArray<Object**>(*total_argc));
for (int i = 0; i < args_count; i++) {
Handle<Object> val = Handle<Object>(frame->GetParameter(i));
- param_data[bound_argc + i] = val;
+ param_data[bound_argc + i] = val.location();
}
return param_data;
}
@@ -7979,17 +7997,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
int bound_argc = 0;
if (!args[1]->IsNull()) {
CONVERT_ARG_CHECKED(JSArray, params, 1);
- RUNTIME_ASSERT(params->HasFastTypeElements());
+ RUNTIME_ASSERT(params->HasFastElements());
bound_args = Handle<FixedArray>(FixedArray::cast(params->elements()));
bound_argc = Smi::cast(params->length())->value();
}
int total_argc = 0;
- SmartArrayPointer<Handle<Object> > param_data =
+ SmartArrayPointer<Object**> param_data =
GetNonBoundArguments(bound_argc, &total_argc);
for (int i = 0; i < bound_argc; i++) {
Handle<Object> val = Handle<Object>(bound_args->get(i));
- param_data[i] = val;
+ param_data[i] = val.location();
}
bool exception = false;
@@ -8289,8 +8307,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- // The least significant bit (after untagging) indicates whether the
- // function is currently optimized, regardless of reason.
if (!V8::UseCrankshaft()) {
return Smi::FromInt(4); // 4 == "never".
}
@@ -8463,11 +8479,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
argv[i] = Handle<Object>(object);
}
- bool threw;
+ bool threw = false;
Handle<JSReceiver> hfun(fun);
Handle<Object> hreceiver(receiver);
- Handle<Object> result =
- Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
+ Handle<Object> result = Execution::Call(
+ hfun, hreceiver, argc, reinterpret_cast<Object***>(argv), &threw, true);
if (threw) return Failure::Exception();
return *result;
@@ -8630,10 +8646,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
}
// The slot was found in a JSObject, either a context extension object,
- // the global object, or the subject of a with. Try to delete it
- // (respecting DONT_DELETE).
+ // the global object, or an arguments object. Try to delete it
+ // (respecting DONT_DELETE). For consistency with V8's usual behavior,
+ // which allows deleting all parameters in functions that mention
+ // 'arguments', we do this even for the case of slots found on an
+ // arguments object. The slot was found on an arguments object if the
+ // index is non-negative.
Handle<JSObject> object = Handle<JSObject>::cast(holder);
- return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
+ if (index >= 0) {
+ return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
+ } else {
+ return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
+ }
}
@@ -8718,19 +8742,24 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
&attributes,
&binding_flags);
- // If the index is non-negative, the slot has been found in a context.
+ // If the index is non-negative, the slot has been found in a local
+ // variable or a parameter. Read it from the context object or the
+ // arguments object.
if (index >= 0) {
- ASSERT(holder->IsContext());
- // If the "property" we were looking for is a local variable, the
- // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
+ // If the "property" we were looking for is a local variable or an
+ // argument in a context, the receiver is the global object; see
+ // ECMA-262, 3rd., 10.1.6 and 10.2.3.
//
- // Use the hole as the receiver to signal that the receiver is implicit
- // and that the global receiver should be used (as distinguished from an
- // explicit receiver that happens to be a global object).
+ // Use the hole as the receiver to signal that the receiver is
+ // implicit and that the global receiver should be used.
Handle<Object> receiver = isolate->factory()->the_hole_value();
- Object* value = Context::cast(*holder)->get(index);
+ MaybeObject* value = (holder->IsContext())
+ ? Context::cast(*holder)->get(index)
+ : JSObject::cast(*holder)->GetElement(index);
// Check for uninitialized bindings.
- if (binding_flags == MUTABLE_CHECK_INITIALIZED && value->IsTheHole()) {
+ if (holder->IsContext() &&
+ binding_flags == MUTABLE_CHECK_INITIALIZED &&
+ value->IsTheHole()) {
Handle<Object> reference_error =
isolate->factory()->NewReferenceError("not_defined",
HandleVector(&name, 1));
@@ -8740,18 +8769,25 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
}
}
- // Otherwise, if the slot was found the holder is a context extension
- // object, subject of a with, or a global object. We read the named
- // property from it.
- if (!holder.is_null()) {
- Handle<JSObject> object = Handle<JSObject>::cast(holder);
- ASSERT(object->HasProperty(*name));
+ // If the holder is found, we read the property from it.
+ if (!holder.is_null() && holder->IsJSObject()) {
+ ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
+ JSObject* object = JSObject::cast(*holder);
+ Object* receiver;
+ if (object->IsGlobalObject()) {
+ receiver = GlobalObject::cast(object)->global_receiver();
+ } else if (context->is_exception_holder(*holder)) {
+ // Use the hole as the receiver to signal that the receiver is
+ // implicit and that the global receiver should be used.
+ receiver = isolate->heap()->the_hole_value();
+ } else {
+ receiver = ComputeReceiverForNonGlobal(isolate, object);
+ }
+
// GetProperty below can cause GC.
- Handle<Object> receiver_handle(object->IsGlobalObject()
- ? GlobalObject::cast(*object)->global_receiver()
- : ComputeReceiverForNonGlobal(isolate, *object));
+ Handle<Object> receiver_handle(receiver);
- // No need to unhole the value here. This is taken care of by the
+ // No need to unhole the value here. This is taken care of by the
// GetProperty function.
MaybeObject* value = object->GetProperty(*name);
return MakePair(value, *receiver_handle);
@@ -8804,37 +8840,45 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
&binding_flags);
if (index >= 0) {
- // The property was found in a context slot.
- Handle<Context> context = Handle<Context>::cast(holder);
- if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
- context->get(index)->IsTheHole()) {
- Handle<Object> error =
- isolate->factory()->NewReferenceError("not_defined",
- HandleVector(&name, 1));
- return isolate->Throw(*error);
- }
- // Ignore if read_only variable.
- if ((attributes & READ_ONLY) == 0) {
- // Context is a fixed array and set cannot fail.
- context->set(index, *value);
- } else if (strict_mode == kStrictMode) {
- // Setting read only property in strict mode.
- Handle<Object> error =
- isolate->factory()->NewTypeError("strict_cannot_assign",
- HandleVector(&name, 1));
- return isolate->Throw(*error);
+ if (holder->IsContext()) {
+ Handle<Context> context = Handle<Context>::cast(holder);
+ if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
+ context->get(index)->IsTheHole()) {
+ Handle<Object> error =
+ isolate->factory()->NewReferenceError("not_defined",
+ HandleVector(&name, 1));
+ return isolate->Throw(*error);
+ }
+ // Ignore if read_only variable.
+ if ((attributes & READ_ONLY) == 0) {
+ // Context is a fixed array and set cannot fail.
+ context->set(index, *value);
+ } else if (strict_mode == kStrictMode) {
+ // Setting read only property in strict mode.
+ Handle<Object> error =
+ isolate->factory()->NewTypeError("strict_cannot_assign",
+ HandleVector(&name, 1));
+ return isolate->Throw(*error);
+ }
+ } else {
+ ASSERT((attributes & READ_ONLY) == 0);
+ Handle<Object> result =
+ SetElement(Handle<JSObject>::cast(holder), index, value, strict_mode);
+ if (result.is_null()) {
+ ASSERT(isolate->has_pending_exception());
+ return Failure::Exception();
+ }
}
return *value;
}
- // Slow case: The property is not in a context slot. It is either in a
- // context extension object, a property of the subject of a with, or a
- // property of the global object.
- Handle<JSObject> object;
+ // Slow case: The property is not in a FixedArray context.
+ // It is either in an JSObject extension context or it was not found.
+ Handle<JSObject> context_ext;
if (!holder.is_null()) {
- // The property exists on the holder.
- object = Handle<JSObject>::cast(holder);
+ // The property exists in the extension context.
+ context_ext = Handle<JSObject>::cast(holder);
} else {
// The property was not found.
ASSERT(attributes == ABSENT);
@@ -8842,21 +8886,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
if (strict_mode == kStrictMode) {
// Throw in strict mode (assignment to undefined variable).
Handle<Object> error =
- isolate->factory()->NewReferenceError(
- "not_defined", HandleVector(&name, 1));
+ isolate->factory()->NewReferenceError(
+ "not_defined", HandleVector(&name, 1));
return isolate->Throw(*error);
}
- // In non-strict mode, the property is added to the global object.
+ // In non-strict mode, the property is stored in the global context.
attributes = NONE;
- object = Handle<JSObject>(isolate->context()->global());
+ context_ext = Handle<JSObject>(isolate->context()->global());
}
- // Set the property if it's not read only or doesn't yet exist.
+ // Set the property, but ignore if read_only variable on the context
+ // extension object itself.
if ((attributes & READ_ONLY) == 0 ||
- (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
+ (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, value, NONE, strict_mode));
+ SetProperty(context_ext, name, value, NONE, strict_mode));
} else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
// Setting read only property in strict mode.
Handle<Object> error =
@@ -9076,10 +9121,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
FlattenString(str);
CONVERT_ARG_CHECKED(JSArray, output, 1);
-
- MaybeObject* maybe_result_array =
- output->EnsureCanContainNonSmiElements();
- if (maybe_result_array->IsFailure()) return maybe_result_array;
RUNTIME_ASSERT(output->HasFastElements());
AssertNoAllocation no_allocation;
@@ -9265,9 +9306,6 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
PropertyAttributes attributes = ABSENT;
BindingFlags binding_flags;
while (true) {
- // Don't follow context chains in Context::Lookup and implement the loop
- // up the context chain here, so that we can know the context where eval
- // was found.
receiver = context->Lookup(isolate->factory()->eval_symbol(),
FOLLOW_PROTOTYPE_CHAIN,
&index,
@@ -9383,7 +9421,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
ASSERT(args.length() == 2);
CONVERT_CHECKED(JSArray, array, args[0]);
CONVERT_CHECKED(JSObject, element, args[1]);
- RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
+ RUNTIME_ASSERT(array->HasFastElements());
int length = Smi::cast(array->length())->value();
FixedArray* elements = FixedArray::cast(array->elements());
for (int i = 0; i < length; i++) {
@@ -9466,11 +9504,9 @@ class ArrayConcatVisitor {
isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
Handle<Map> map;
if (fast_elements_) {
- map = isolate_->factory()->GetElementsTransitionMap(array,
- FAST_ELEMENTS);
+ map = isolate_->factory()->GetFastElementsMap(Handle<Map>(array->map()));
} else {
- map = isolate_->factory()->GetElementsTransitionMap(array,
- DICTIONARY_ELEMENTS);
+ map = isolate_->factory()->GetSlowElementsMap(Handle<Map>(array->map()));
}
array->set_map(*map);
array->set_length(*length);
@@ -9614,7 +9650,6 @@ static void CollectElementIndices(Handle<JSObject> object,
List<uint32_t>* indices) {
ElementsKind kind = object->GetElementsKind();
switch (kind) {
- case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(object->elements()));
uint32_t length = static_cast<uint32_t>(elements->length());
@@ -9734,7 +9769,6 @@ static bool IterateElements(Isolate* isolate,
ArrayConcatVisitor* visitor) {
uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
switch (receiver->GetElementsKind()) {
- case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
// Run through the elements FixedArray and use HasElement and GetElement
// to check the prototype for missing elements.
@@ -9963,17 +9997,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
CONVERT_CHECKED(JSArray, to, args[1]);
FixedArrayBase* new_elements = from->elements();
MaybeObject* maybe_new_map;
- ElementsKind elements_kind;
if (new_elements->map() == isolate->heap()->fixed_array_map() ||
new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
- elements_kind = FAST_ELEMENTS;
+ maybe_new_map = to->map()->GetFastElementsMap();
} else if (new_elements->map() ==
isolate->heap()->fixed_double_array_map()) {
- elements_kind = FAST_DOUBLE_ELEMENTS;
+ maybe_new_map = to->map()->GetFastDoubleElementsMap();
} else {
- elements_kind = DICTIONARY_ELEMENTS;
+ maybe_new_map = to->map()->GetSlowElementsMap();
}
- maybe_new_map = to->GetElementsTransitionMap(elements_kind);
Object* new_map;
if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
to->set_map(Map::cast(new_map));
@@ -10058,9 +10090,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
}
return *isolate->factory()->NewJSArrayWithElements(keys);
} else {
- ASSERT(array->HasFastElements() ||
- array->HasFastSmiOnlyElements() ||
- array->HasFastDoubleElements());
+ ASSERT(array->HasFastElements() || array->HasFastDoubleElements());
Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
// -1 means start of array.
single_interval->set(0, Smi::FromInt(-1));
@@ -10179,8 +10209,8 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
case CALLBACKS: {
Object* structure = result->GetCallbackObject();
if (structure->IsForeign() || structure->IsAccessorInfo()) {
- MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
- receiver, structure, name);
+ MaybeObject* maybe_value = receiver->GetPropertyWithCallback(
+ receiver, structure, name, result->holder());
if (!maybe_value->ToObject(&value)) {
if (maybe_value->IsRetryAfterGC()) return maybe_value;
ASSERT(maybe_value->IsException());
@@ -11430,53 +11460,48 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
int target_start_position = RelocInfo::kNoPosition;
Handle<SharedFunctionInfo> target;
while (!done) {
- { // Extra scope for iterator and no-allocation.
- isolate->heap()->EnsureHeapIsIterable();
- AssertNoAllocation no_alloc_during_heap_iteration;
- HeapIterator iterator;
- for (HeapObject* obj = iterator.next();
- obj != NULL; obj = iterator.next()) {
- if (obj->IsSharedFunctionInfo()) {
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
- if (shared->script() == *script) {
- // If the SharedFunctionInfo found has the requested script data and
- // contains the source position it is a candidate.
- int start_position = shared->function_token_position();
- if (start_position == RelocInfo::kNoPosition) {
- start_position = shared->start_position();
- }
- if (start_position <= position &&
- position <= shared->end_position()) {
- // If there is no candidate or this function is within the current
- // candidate this is the new candidate.
- if (target.is_null()) {
- target_start_position = start_position;
- target = shared;
- } else {
- if (target_start_position == start_position &&
- shared->end_position() == target->end_position()) {
- // If a top-level function contain only one function
- // declartion the source for the top-level and the
- // function is the same. In that case prefer the non
- // top-level function.
- if (!shared->is_toplevel()) {
- target_start_position = start_position;
- target = shared;
- }
- } else if (target_start_position <= start_position &&
- shared->end_position() <= target->end_position()) {
- // This containment check includes equality as a function
- // inside a top-level function can share either start or end
- // position with the top-level function.
+ HeapIterator iterator;
+ for (HeapObject* obj = iterator.next();
+ obj != NULL; obj = iterator.next()) {
+ if (obj->IsSharedFunctionInfo()) {
+ Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
+ if (shared->script() == *script) {
+ // If the SharedFunctionInfo found has the requested script data and
+ // contains the source position it is a candidate.
+ int start_position = shared->function_token_position();
+ if (start_position == RelocInfo::kNoPosition) {
+ start_position = shared->start_position();
+ }
+ if (start_position <= position &&
+ position <= shared->end_position()) {
+ // If there is no candidate or this function is within the current
+ // candidate this is the new candidate.
+ if (target.is_null()) {
+ target_start_position = start_position;
+ target = shared;
+ } else {
+ if (target_start_position == start_position &&
+ shared->end_position() == target->end_position()) {
+ // If a top-level function contain only one function
+ // declartion the source for the top-level and the function is
+ // the same. In that case prefer the non top-level function.
+ if (!shared->is_toplevel()) {
target_start_position = start_position;
target = shared;
}
+ } else if (target_start_position <= start_position &&
+ shared->end_position() <= target->end_position()) {
+ // This containment check includes equality as a function inside
+ // a top-level function can share either start or end position
+ // with the top-level function.
+ target_start_position = start_position;
+ target = shared;
}
}
}
}
- } // End for loop.
- } // End No allocation scope.
+ }
+ }
if (target.is_null()) {
return isolate->heap()->undefined_value();
@@ -11491,7 +11516,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
// functions which might contain the requested source position.
CompileLazyShared(target, KEEP_EXCEPTION);
}
- } // End while loop.
+ }
return *target;
}
@@ -11857,13 +11882,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
&sinfo, function_context);
// Invoke the evaluation function and return the result.
- Handle<Object> argv[] = { arguments, source };
+ const int argc = 2;
+ Object** argv[argc] = { arguments.location(),
+ Handle<Object>::cast(source).location() };
Handle<Object> result =
- Execution::Call(Handle<JSFunction>::cast(evaluation_function),
- receiver,
- ARRAY_SIZE(argv),
- argv,
- &has_pending_exception);
+ Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver,
+ argc, argv, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
// Skip the global proxy as it has no properties and always delegates to the
@@ -11942,8 +11966,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
Handle<Object> result =
Execution::Call(compiled_function, receiver, 0, NULL,
&has_pending_exception);
- // Clear the oneshot breakpoints so that the debugger does not step further.
- isolate->debug()->ClearStepping();
if (has_pending_exception) return Failure::Exception();
return *result;
}
@@ -11971,14 +11993,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
// Return result as a JS array.
Handle<JSObject> result =
isolate->factory()->NewJSObject(isolate->array_function());
- isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
+ Handle<JSArray>::cast(result)->SetContent(*instances);
return *result;
}
// Helper function used by Runtime_DebugReferencedBy below.
-static int DebugReferencedBy(HeapIterator* iterator,
- JSObject* target,
+static int DebugReferencedBy(JSObject* target,
Object* instance_filter, int max_references,
FixedArray* instances, int instances_size,
JSFunction* arguments_function) {
@@ -11988,8 +12009,9 @@ static int DebugReferencedBy(HeapIterator* iterator,
// Iterate the heap.
int count = 0;
JSObject* last = NULL;
+ HeapIterator iterator;
HeapObject* heap_obj = NULL;
- while (((heap_obj = iterator->next()) != NULL) &&
+ while (((heap_obj = iterator.next()) != NULL) &&
(max_references == 0 || count < max_references)) {
// Only look at all JSObjects.
if (heap_obj->IsJSObject()) {
@@ -12054,11 +12076,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
ASSERT(args.length() == 3);
// First perform a full GC in order to avoid references from dead objects.
- isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
- // The heap iterator reserves the right to do a GC to make the heap iterable.
- // Due to the GC above we know it won't need to do that, but it seems cleaner
- // to get the heap iterator constructed before we start having unprotected
- // Object* locals that are not protected by handles.
+ isolate->heap()->CollectAllGarbage(false);
// Check parameters.
CONVERT_CHECKED(JSObject, target, args[0]);
@@ -12068,7 +12086,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
RUNTIME_ASSERT(max_references >= 0);
-
// Get the constructor function for context extension and arguments array.
JSObject* arguments_boilerplate =
isolate->context()->global_context()->arguments_boilerplate();
@@ -12077,9 +12094,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Get the number of referencing objects.
int count;
- HeapIterator heap_iterator;
- count = DebugReferencedBy(&heap_iterator,
- target, instance_filter, max_references,
+ count = DebugReferencedBy(target, instance_filter, max_references,
NULL, 0, arguments_function);
// Allocate an array to hold the result.
@@ -12090,34 +12105,30 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
FixedArray* instances = FixedArray::cast(object);
// Fill the referencing objects.
- // AllocateFixedArray above does not make the heap non-iterable.
- ASSERT(HEAP->IsHeapIterable());
- HeapIterator heap_iterator2;
- count = DebugReferencedBy(&heap_iterator2,
- target, instance_filter, max_references,
+ count = DebugReferencedBy(target, instance_filter, max_references,
instances, count, arguments_function);
// Return result as JS array.
Object* result;
- MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
+ { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
isolate->context()->global_context()->array_function());
- if (!maybe_result->ToObject(&result)) return maybe_result;
- return JSArray::cast(result)->SetContent(instances);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ JSArray::cast(result)->SetContent(instances);
+ return result;
}
// Helper function used by Runtime_DebugConstructedBy below.
-static int DebugConstructedBy(HeapIterator* iterator,
- JSFunction* constructor,
- int max_references,
- FixedArray* instances,
- int instances_size) {
+static int DebugConstructedBy(JSFunction* constructor, int max_references,
+ FixedArray* instances, int instances_size) {
AssertNoAllocation no_alloc;
// Iterate the heap.
int count = 0;
+ HeapIterator iterator;
HeapObject* heap_obj = NULL;
- while (((heap_obj = iterator->next()) != NULL) &&
+ while (((heap_obj = iterator.next()) != NULL) &&
(max_references == 0 || count < max_references)) {
// Only look at all JSObjects.
if (heap_obj->IsJSObject()) {
@@ -12145,7 +12156,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
ASSERT(args.length() == 2);
// First perform a full GC in order to avoid dead objects.
- isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
+ isolate->heap()->CollectAllGarbage(false);
// Check parameters.
CONVERT_CHECKED(JSFunction, constructor, args[0]);
@@ -12154,12 +12165,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Get the number of referencing objects.
int count;
- HeapIterator heap_iterator;
- count = DebugConstructedBy(&heap_iterator,
- constructor,
- max_references,
- NULL,
- 0);
+ count = DebugConstructedBy(constructor, max_references, NULL, 0);
// Allocate an array to hold the result.
Object* object;
@@ -12168,14 +12174,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
}
FixedArray* instances = FixedArray::cast(object);
- ASSERT(HEAP->IsHeapIterable());
// Fill the referencing objects.
- HeapIterator heap_iterator2;
- count = DebugConstructedBy(&heap_iterator2,
- constructor,
- max_references,
- instances,
- count);
+ count = DebugConstructedBy(constructor, max_references, instances, count);
// Return result as JS array.
Object* result;
@@ -12183,7 +12183,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
isolate->context()->global_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- return JSArray::cast(result)->SetContent(instances);
+ JSArray::cast(result)->SetContent(instances);
+ return result;
}
@@ -12247,15 +12248,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
}
-static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
- Script* script,
+static int FindSharedFunctionInfosForScript(Script* script,
FixedArray* buffer) {
AssertNoAllocation no_allocations;
+
int counter = 0;
int buffer_size = buffer->length();
- for (HeapObject* obj = iterator->next();
- obj != NULL;
- obj = iterator->next()) {
+ HeapIterator iterator;
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
ASSERT(obj != NULL);
if (!obj->IsSharedFunctionInfo()) {
continue;
@@ -12281,30 +12281,16 @@ RUNTIME_FUNCTION(MaybeObject*,
HandleScope scope(isolate);
CONVERT_CHECKED(JSValue, script_value, args[0]);
-
Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
const int kBufferSize = 32;
Handle<FixedArray> array;
array = isolate->factory()->NewFixedArray(kBufferSize);
- int number;
- {
- isolate->heap()->EnsureHeapIsIterable();
- AssertNoAllocation no_allocations;
- HeapIterator heap_iterator;
- Script* scr = *script;
- FixedArray* arr = *array;
- number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
- }
+ int number = FindSharedFunctionInfosForScript(*script, *array);
if (number > kBufferSize) {
array = isolate->factory()->NewFixedArray(number);
- isolate->heap()->EnsureHeapIsIterable();
- AssertNoAllocation no_allocations;
- HeapIterator heap_iterator;
- Script* scr = *script;
- FixedArray* arr = *array;
- FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
+ FindSharedFunctionInfosForScript(*script, *array);
}
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
@@ -12785,8 +12771,6 @@ static Handle<Object> Runtime_GetScriptFromScriptName(
// Scan the heap for Script objects to find the script with the requested
// script data.
Handle<Script> script;
- script_name->GetHeap()->EnsureHeapIsIterable();
- AssertNoAllocation no_allocation_during_heap_iteration;
HeapIterator iterator;
HeapObject* obj = NULL;
while (script.is_null() && ((obj = iterator.next()) != NULL)) {
@@ -12998,11 +12982,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
// TODO(antonm): consider passing a receiver when constructing a cache.
Handle<Object> receiver(isolate->global_context()->global());
// This handle is nor shared, nor used later, so it's safe.
- Handle<Object> argv[] = { key_handle };
- bool pending_exception;
+ Object** argv[] = { key_handle.location() };
+ bool pending_exception = false;
value = Execution::Call(factory,
receiver,
- ARRAY_SIZE(argv),
+ 1,
argv,
&pending_exception);
if (pending_exception) return Failure::Exception();
@@ -13155,7 +13139,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
return isolate->heap()->ToBoolean(obj->Has##Name()); \
}
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
@@ -13239,9 +13222,6 @@ void Runtime::PerformGC(Object* result) {
Isolate* isolate = Isolate::Current();
Failure* failure = Failure::cast(result);
if (failure->IsRetryAfterGC()) {
- if (isolate->heap()->new_space()->AddFreshPage()) {
- return;
- }
// Try to do a garbage collection; ignore it if it fails. The C
// entry stub will throw an out-of-memory exception in that case.
isolate->heap()->CollectGarbage(failure->allocation_space());
@@ -13249,7 +13229,7 @@ void Runtime::PerformGC(Object* result) {
// Handle last resort GC and make sure to allow future allocations
// to grow the heap without causing GCs (if possible).
isolate->counters()->gc_last_resort_from_js()->Increment();
- isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
+ isolate->heap()->CollectAllGarbage(false);
}
}