Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: src/runtime.cc

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 24 matching lines...) Expand all
35 #include "bootstrapper.h" 35 #include "bootstrapper.h"
36 #include "codegen.h" 36 #include "codegen.h"
37 #include "compilation-cache.h" 37 #include "compilation-cache.h"
38 #include "compiler.h" 38 #include "compiler.h"
39 #include "cpu.h" 39 #include "cpu.h"
40 #include "dateparser-inl.h" 40 #include "dateparser-inl.h"
41 #include "debug.h" 41 #include "debug.h"
42 #include "deoptimizer.h" 42 #include "deoptimizer.h"
43 #include "execution.h" 43 #include "execution.h"
44 #include "global-handles.h" 44 #include "global-handles.h"
45 #include "isolate-inl.h"
45 #include "jsregexp.h" 46 #include "jsregexp.h"
46 #include "json-parser.h" 47 #include "json-parser.h"
47 #include "liveedit.h" 48 #include "liveedit.h"
48 #include "liveobjectlist-inl.h" 49 #include "liveobjectlist-inl.h"
49 #include "misc-intrinsics.h" 50 #include "misc-intrinsics.h"
50 #include "parser.h" 51 #include "parser.h"
51 #include "platform.h" 52 #include "platform.h"
52 #include "runtime-profiler.h" 53 #include "runtime-profiler.h"
53 #include "runtime.h" 54 #include "runtime.h"
54 #include "scopeinfo.h" 55 #include "scopeinfo.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 if (!maybe_result->ToObject(&result)) return maybe_result; 171 if (!maybe_result->ToObject(&result)) return maybe_result;
171 } 172 }
172 } 173 }
173 } 174 }
174 } 175 }
175 176
176 // Deep copy local elements. 177 // Deep copy local elements.
177 // Pixel elements cannot be created using an object literal. 178 // Pixel elements cannot be created using an object literal.
178 ASSERT(!copy->HasExternalArrayElements()); 179 ASSERT(!copy->HasExternalArrayElements());
179 switch (copy->GetElementsKind()) { 180 switch (copy->GetElementsKind()) {
181 case FAST_SMI_ONLY_ELEMENTS:
180 case FAST_ELEMENTS: { 182 case FAST_ELEMENTS: {
181 FixedArray* elements = FixedArray::cast(copy->elements()); 183 FixedArray* elements = FixedArray::cast(copy->elements());
182 if (elements->map() == heap->fixed_cow_array_map()) { 184 if (elements->map() == heap->fixed_cow_array_map()) {
183 isolate->counters()->cow_arrays_created_runtime()->Increment(); 185 isolate->counters()->cow_arrays_created_runtime()->Increment();
184 #ifdef DEBUG 186 #ifdef DEBUG
185 for (int i = 0; i < elements->length(); i++) { 187 for (int i = 0; i < elements->length(); i++) {
186 ASSERT(!elements->get(i)->IsJSObject()); 188 ASSERT(!elements->get(i)->IsJSObject());
187 } 189 }
188 #endif 190 #endif
189 } else { 191 } else {
190 for (int i = 0; i < elements->length(); i++) { 192 for (int i = 0; i < elements->length(); i++) {
191 Object* value = elements->get(i); 193 Object* value = elements->get(i);
194 ASSERT(value->IsSmi() ||
195 value->IsTheHole() ||
196 (copy->GetElementsKind() == FAST_ELEMENTS));
192 if (value->IsJSObject()) { 197 if (value->IsJSObject()) {
193 JSObject* js_object = JSObject::cast(value); 198 JSObject* js_object = JSObject::cast(value);
194 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, 199 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
195 js_object); 200 js_object);
196 if (!maybe_result->ToObject(&result)) return maybe_result; 201 if (!maybe_result->ToObject(&result)) return maybe_result;
197 } 202 }
198 elements->set(i, result); 203 elements->set(i, result);
199 } 204 }
200 } 205 }
201 } 206 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 Handle<JSFunction> constructor( 430 Handle<JSFunction> constructor(
426 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); 431 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
427 Handle<Object> object = isolate->factory()->NewJSObject(constructor); 432 Handle<Object> object = isolate->factory()->NewJSObject(constructor);
428 433
429 const bool is_cow = 434 const bool is_cow =
430 (elements->map() == isolate->heap()->fixed_cow_array_map()); 435 (elements->map() == isolate->heap()->fixed_cow_array_map());
431 Handle<FixedArray> copied_elements = 436 Handle<FixedArray> copied_elements =
432 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); 437 is_cow ? elements : isolate->factory()->CopyFixedArray(elements);
433 438
434 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); 439 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
440 bool has_non_smi = false;
435 if (is_cow) { 441 if (is_cow) {
436 #ifdef DEBUG
437 // Copy-on-write arrays must be shallow (and simple). 442 // Copy-on-write arrays must be shallow (and simple).
438 for (int i = 0; i < content->length(); i++) { 443 if (FLAG_smi_only_arrays) {
439 ASSERT(!content->get(i)->IsFixedArray()); 444 for (int i = 0; i < content->length(); i++) {
445 Object* current = content->get(i);
446 ASSERT(!current->IsFixedArray());
447 if (!current->IsSmi() && !current->IsTheHole()) {
448 has_non_smi = true;
449 }
450 }
451 } else {
452 #if DEBUG
453 for (int i = 0; i < content->length(); i++) {
454 ASSERT(!content->get(i)->IsFixedArray());
455 }
456 #endif
440 } 457 }
441 #endif
442 } else { 458 } else {
443 for (int i = 0; i < content->length(); i++) { 459 for (int i = 0; i < content->length(); i++) {
444 if (content->get(i)->IsFixedArray()) { 460 Object* current = content->get(i);
461 if (current->IsFixedArray()) {
445 // The value contains the constant_properties of a 462 // The value contains the constant_properties of a
446 // simple object or array literal. 463 // simple object or array literal.
447 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); 464 Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
448 Handle<Object> result = 465 Handle<Object> result =
449 CreateLiteralBoilerplate(isolate, literals, fa); 466 CreateLiteralBoilerplate(isolate, literals, fa);
450 if (result.is_null()) return result; 467 if (result.is_null()) return result;
451 content->set(i, *result); 468 content->set(i, *result);
469 has_non_smi = true;
470 } else {
471 if (!current->IsSmi() && !current->IsTheHole()) {
472 has_non_smi = true;
473 }
452 } 474 }
453 } 475 }
454 } 476 }
455 477
456 // Set the elements. 478 // Set the elements.
457 Handle<JSArray>::cast(object)->SetContent(*content); 479 Handle<JSArray> js_object(Handle<JSArray>::cast(object));
480 isolate->factory()->SetContent(js_object, content);
481
482 if (FLAG_smi_only_arrays) {
483 if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
484 isolate->factory()->EnsureCanContainNonSmiElements(js_object);
485 }
486 }
487
458 return object; 488 return object;
459 } 489 }
460 490
461 491
462 static Handle<Object> CreateLiteralBoilerplate( 492 static Handle<Object> CreateLiteralBoilerplate(
463 Isolate* isolate, 493 Isolate* isolate,
464 Handle<FixedArray> literals, 494 Handle<FixedArray> literals,
465 Handle<FixedArray> array) { 495 Handle<FixedArray> array) {
466 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 496 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
467 const bool kHasNoFunctionLiteral = false; 497 const bool kHasNoFunctionLiteral = false;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 weakmap->set_table(*table); 708 weakmap->set_table(*table);
679 weakmap->set_next(Smi::FromInt(0)); 709 weakmap->set_next(Smi::FromInt(0));
680 return *weakmap; 710 return *weakmap;
681 } 711 }
682 712
683 713
684 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) { 714 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
685 NoHandleAllocation ha; 715 NoHandleAllocation ha;
686 ASSERT(args.length() == 2); 716 ASSERT(args.length() == 2);
687 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0); 717 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
688 // TODO(mstarzinger): Currently we cannot use JSProxy objects as keys 718 CONVERT_ARG_CHECKED(JSReceiver, key, 1);
689 // because they cannot be cast to JSObject to get an identity hash code. 719 return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
690 CONVERT_ARG_CHECKED(JSObject, key, 1);
691 return weakmap->table()->Lookup(*key);
692 } 720 }
693 721
694 722
695 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) { 723 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
696 HandleScope scope(isolate); 724 HandleScope scope(isolate);
697 ASSERT(args.length() == 3); 725 ASSERT(args.length() == 3);
698 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0); 726 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
699 // TODO(mstarzinger): See Runtime_WeakMapGet above. 727 CONVERT_ARG_CHECKED(JSReceiver, key, 1);
700 CONVERT_ARG_CHECKED(JSObject, key, 1);
701 Handle<Object> value(args[2]); 728 Handle<Object> value(args[2]);
702 Handle<ObjectHashTable> table(weakmap->table()); 729 Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
703 Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value); 730 Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
704 weakmap->set_table(*new_table); 731 weakmap->set_table(*new_table);
705 return *value; 732 return *value;
706 } 733 }
707 734
708 735
709 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { 736 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
710 NoHandleAllocation ha; 737 NoHandleAllocation ha;
711 ASSERT(args.length() == 1); 738 ASSERT(args.length() == 1);
712 Object* obj = args[0]; 739 Object* obj = args[0];
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 // assign to it when evaluating the assignment for "const x = 1231 // assign to it when evaluating the assignment for "const x =
1205 // <expr>" the initial value is the hole. 1232 // <expr>" the initial value is the hole.
1206 bool is_const_property = value->IsTheHole(); 1233 bool is_const_property = value->IsTheHole();
1207 bool is_function_declaration = false; 1234 bool is_function_declaration = false;
1208 if (value->IsUndefined() || is_const_property) { 1235 if (value->IsUndefined() || is_const_property) {
1209 // Lookup the property in the global object, and don't set the 1236 // Lookup the property in the global object, and don't set the
1210 // value of the variable if the property is already there. 1237 // value of the variable if the property is already there.
1211 LookupResult lookup; 1238 LookupResult lookup;
1212 global->Lookup(*name, &lookup); 1239 global->Lookup(*name, &lookup);
1213 if (lookup.IsProperty()) { 1240 if (lookup.IsProperty()) {
1214 // Determine if the property is local by comparing the holder 1241 // We found an existing property. Unless it was an interceptor
1215 // against the global object. The information will be used to 1242 // that claims the property is absent, skip this declaration.
1216 // avoid throwing re-declaration errors when declaring 1243 if (lookup.type() != INTERCEPTOR) {
1217 // variables or constants that exist in the prototype chain.
1218 bool is_local = (*global == lookup.holder());
1219 // Get the property attributes and determine if the property is
1220 // read-only.
1221 PropertyAttributes attributes = global->GetPropertyAttribute(*name);
1222 bool is_read_only = (attributes & READ_ONLY) != 0;
1223 if (lookup.type() == INTERCEPTOR) {
1224 // If the interceptor says the property is there, we
1225 // just return undefined without overwriting the property.
1226 // Otherwise, we continue to setting the property.
1227 if (attributes != ABSENT) {
1228 // Check if the existing property conflicts with regards to const.
1229 if (is_local && (is_read_only || is_const_property)) {
1230 const char* type = (is_read_only) ? "const" : "var";
1231 return ThrowRedeclarationError(isolate, type, name);
1232 };
1233 // The property already exists without conflicting: Go to
1234 // the next declaration.
1235 continue;
1236 }
1237 // Fall-through and introduce the absent property by using
1238 // SetProperty.
1239 } else {
1240 // For const properties, we treat a callback with this name
1241 // even in the prototype as a conflicting declaration.
1242 if (is_const_property && (lookup.type() == CALLBACKS)) {
1243 return ThrowRedeclarationError(isolate, "const", name);
1244 }
1245 // Otherwise, we check for locally conflicting declarations.
1246 if (is_local && (is_read_only || is_const_property)) {
1247 const char* type = (is_read_only) ? "const" : "var";
1248 return ThrowRedeclarationError(isolate, type, name);
1249 }
1250 // The property already exists without conflicting: Go to
1251 // the next declaration.
1252 continue; 1244 continue;
1253 } 1245 }
1246 PropertyAttributes attributes = global->GetPropertyAttribute(*name);
1247 if (attributes != ABSENT) {
1248 continue;
1249 }
1250 // Fall-through and introduce the absent property by using
1251 // SetProperty.
1254 } 1252 }
1255 } else { 1253 } else {
1256 is_function_declaration = true; 1254 is_function_declaration = true;
1257 // Copy the function and update its context. Use it as value. 1255 // Copy the function and update its context. Use it as value.
1258 Handle<SharedFunctionInfo> shared = 1256 Handle<SharedFunctionInfo> shared =
1259 Handle<SharedFunctionInfo>::cast(value); 1257 Handle<SharedFunctionInfo>::cast(value);
1260 Handle<JSFunction> function = 1258 Handle<JSFunction> function =
1261 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, 1259 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
1262 context, 1260 context,
1263 TENURED); 1261 TENURED);
1264 value = function; 1262 value = function;
1265 } 1263 }
1266 1264
1267 LookupResult lookup; 1265 LookupResult lookup;
1268 global->LocalLookup(*name, &lookup); 1266 global->LocalLookup(*name, &lookup);
1269 1267
1270 // There's a local property that we need to overwrite because
1271 // we're either declaring a function or there's an interceptor
1272 // that claims the property is absent.
1273 //
1274 // Check for conflicting re-declarations. We cannot have
1275 // conflicting types in case of intercepted properties because
1276 // they are absent.
1277 if (lookup.IsProperty() &&
1278 (lookup.type() != INTERCEPTOR) &&
1279 (lookup.IsReadOnly() || is_const_property)) {
1280 const char* type = (lookup.IsReadOnly()) ? "const" : "var";
1281 return ThrowRedeclarationError(isolate, type, name);
1282 }
1283
1284 // Compute the property attributes. According to ECMA-262, section 1268 // Compute the property attributes. According to ECMA-262, section
1285 // 13, page 71, the property must be read-only and 1269 // 13, page 71, the property must be read-only and
1286 // non-deletable. However, neither SpiderMonkey nor KJS creates the 1270 // non-deletable. However, neither SpiderMonkey nor KJS creates the
1287 // property as read-only, so we don't either. 1271 // property as read-only, so we don't either.
1288 int attr = NONE; 1272 int attr = NONE;
1289 if ((flags & kDeclareGlobalsEvalFlag) == 0) { 1273 if ((flags & kDeclareGlobalsEvalFlag) == 0) {
1290 attr |= DONT_DELETE; 1274 attr |= DONT_DELETE;
1291 } 1275 }
1292 bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0; 1276 bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0;
1293 if (is_const_property || (is_native && is_function_declaration)) { 1277 if (is_const_property || (is_native && is_function_declaration)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 1312
1329 ASSERT(!isolate->has_pending_exception()); 1313 ASSERT(!isolate->has_pending_exception());
1330 return isolate->heap()->undefined_value(); 1314 return isolate->heap()->undefined_value();
1331 } 1315 }
1332 1316
1333 1317
1334 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { 1318 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1335 HandleScope scope(isolate); 1319 HandleScope scope(isolate);
1336 ASSERT(args.length() == 4); 1320 ASSERT(args.length() == 4);
1337 1321
1338 CONVERT_ARG_CHECKED(Context, context, 0); 1322 // Declarations are always made in a function or global context. In the
1323 // case of eval code, the context passed is the context of the caller,
1324 // which may be some nested context and not the declaration context.
1325 RUNTIME_ASSERT(args[0]->IsContext());
1326 Handle<Context> context(Context::cast(args[0])->declaration_context());
1327
1339 Handle<String> name(String::cast(args[1])); 1328 Handle<String> name(String::cast(args[1]));
1340 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); 1329 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1341 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); 1330 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1342 Handle<Object> initial_value(args[3], isolate); 1331 Handle<Object> initial_value(args[3], isolate);
1343 1332
1344 // Declarations are always done in a function or global context.
1345 context = Handle<Context>(context->declaration_context());
1346
1347 int index; 1333 int index;
1348 PropertyAttributes attributes; 1334 PropertyAttributes attributes;
1349 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; 1335 ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1350 BindingFlags binding_flags; 1336 BindingFlags binding_flags;
1351 Handle<Object> holder = 1337 Handle<Object> holder =
1352 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1338 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1353 1339
1354 if (attributes != ABSENT) { 1340 if (attributes != ABSENT) {
1355 // The name was declared before; check for conflicting 1341 // The name was declared before; check for conflicting re-declarations.
1356 // re-declarations: This is similar to the code in parser.cc in
1357 // the AstBuildingParser::Declare function.
1358 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { 1342 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
1359 // Functions are not read-only. 1343 // Functions are not read-only.
1360 ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); 1344 ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
1361 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var"; 1345 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
1362 return ThrowRedeclarationError(isolate, type, name); 1346 return ThrowRedeclarationError(isolate, type, name);
1363 } 1347 }
1364 1348
1365 // Initialize it if necessary. 1349 // Initialize it if necessary.
1366 if (*initial_value != NULL) { 1350 if (*initial_value != NULL) {
1367 if (index >= 0) { 1351 if (index >= 0) {
1368 // The variable or constant context slot should always be in 1352 ASSERT(holder.is_identical_to(context));
1369 // the function context or the arguments object. 1353 if (((attributes & READ_ONLY) == 0) ||
1370 if (holder->IsContext()) { 1354 context->get(index)->IsTheHole()) {
1371 ASSERT(holder.is_identical_to(context)); 1355 context->set(index, *initial_value);
1372 if (((attributes & READ_ONLY) == 0) ||
1373 context->get(index)->IsTheHole()) {
1374 context->set(index, *initial_value);
1375 }
1376 } else {
1377 // The holder is an arguments object.
1378 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1379 Handle<Object> result = SetElement(arguments, index, initial_value,
1380 kNonStrictMode);
1381 if (result.is_null()) return Failure::Exception();
1382 } 1356 }
1383 } else { 1357 } else {
1384 // Slow case: The property is not in the FixedArray part of the context. 1358 // Slow case: The property is in the context extension object of a
1385 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1359 // function context or the global object of a global context.
1360 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1386 RETURN_IF_EMPTY_HANDLE( 1361 RETURN_IF_EMPTY_HANDLE(
1387 isolate, 1362 isolate,
1388 SetProperty(context_ext, name, initial_value, 1363 SetProperty(object, name, initial_value, mode, kNonStrictMode));
1389 mode, kNonStrictMode));
1390 } 1364 }
1391 } 1365 }
1392 1366
1393 } else { 1367 } else {
1394 // The property is not in the function context. It needs to be 1368 // The property is not in the function context. It needs to be
1395 // "declared" in the function context's extension context, or in the 1369 // "declared" in the function context's extension context or as a
1396 // global context. 1370 // property of the the global object.
1397 Handle<JSObject> context_ext; 1371 Handle<JSObject> object;
1398 if (context->has_extension()) { 1372 if (context->has_extension()) {
1399 // The function context's extension context exists - use it. 1373 object = Handle<JSObject>(JSObject::cast(context->extension()));
1400 context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1401 } else { 1374 } else {
1402 // The function context's extension context does not exists - allocate 1375 // Context extension objects are allocated lazily.
1403 // it. 1376 ASSERT(context->IsFunctionContext());
1404 context_ext = isolate->factory()->NewJSObject( 1377 object = isolate->factory()->NewJSObject(
1405 isolate->context_extension_function()); 1378 isolate->context_extension_function());
1406 // And store it in the extension slot. 1379 context->set_extension(*object);
1407 context->set_extension(*context_ext);
1408 } 1380 }
1409 ASSERT(*context_ext != NULL); 1381 ASSERT(*object != NULL);
1410 1382
1411 // Declare the property by setting it to the initial value if provided, 1383 // Declare the property by setting it to the initial value if provided,
1412 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for 1384 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
1413 // constant declarations). 1385 // constant declarations).
1414 ASSERT(!context_ext->HasLocalProperty(*name)); 1386 ASSERT(!object->HasLocalProperty(*name));
1415 Handle<Object> value(isolate->heap()->undefined_value(), isolate); 1387 Handle<Object> value(isolate->heap()->undefined_value(), isolate);
1416 if (*initial_value != NULL) value = initial_value; 1388 if (*initial_value != NULL) value = initial_value;
1417 // Declaring a const context slot is a conflicting declaration if 1389 // Declaring a const context slot is a conflicting declaration if
1418 // there is a callback with that name in a prototype. It is 1390 // there is a callback with that name in a prototype. It is
1419 // allowed to introduce const variables in 1391 // allowed to introduce const variables in
1420 // JSContextExtensionObjects. They are treated specially in 1392 // JSContextExtensionObjects. They are treated specially in
1421 // SetProperty and no setters are invoked for those since they are 1393 // SetProperty and no setters are invoked for those since they are
1422 // not real JSObjects. 1394 // not real JSObjects.
1423 if (initial_value->IsTheHole() && 1395 if (initial_value->IsTheHole() &&
1424 !context_ext->IsJSContextExtensionObject()) { 1396 !object->IsJSContextExtensionObject()) {
1425 LookupResult lookup; 1397 LookupResult lookup;
1426 context_ext->Lookup(*name, &lookup); 1398 object->Lookup(*name, &lookup);
1427 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { 1399 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
1428 return ThrowRedeclarationError(isolate, "const", name); 1400 return ThrowRedeclarationError(isolate, "const", name);
1429 } 1401 }
1430 } 1402 }
1431 RETURN_IF_EMPTY_HANDLE(isolate, 1403 RETURN_IF_EMPTY_HANDLE(isolate,
1432 SetProperty(context_ext, name, value, mode, 1404 SetProperty(object, name, value, mode,
1433 kNonStrictMode)); 1405 kNonStrictMode));
1434 } 1406 }
1435 1407
1436 return isolate->heap()->undefined_value(); 1408 return isolate->heap()->undefined_value();
1437 } 1409 }
1438 1410
1439 1411
1440 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { 1412 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
1441 NoHandleAllocation nha; 1413 NoHandleAllocation nha;
1442 // args[0] == name 1414 // args[0] == name
(...skipping 15 matching lines...) Expand all
1458 // not be deletable. 1430 // not be deletable.
1459 PropertyAttributes attributes = DONT_DELETE; 1431 PropertyAttributes attributes = DONT_DELETE;
1460 1432
1461 // Lookup the property locally in the global object. If it isn't 1433 // Lookup the property locally in the global object. If it isn't
1462 // there, there is a property with this name in the prototype chain. 1434 // there, there is a property with this name in the prototype chain.
1463 // We follow Safari and Firefox behavior and only set the property 1435 // We follow Safari and Firefox behavior and only set the property
1464 // locally if there is an explicit initialization value that we have 1436 // locally if there is an explicit initialization value that we have
1465 // to assign to the property. 1437 // to assign to the property.
1466 // Note that objects can have hidden prototypes, so we need to traverse 1438 // Note that objects can have hidden prototypes, so we need to traverse
1467 // the whole chain of hidden prototypes to do a 'local' lookup. 1439 // the whole chain of hidden prototypes to do a 'local' lookup.
1468 JSObject* real_holder = global; 1440 Object* object = global;
1469 LookupResult lookup; 1441 LookupResult lookup;
1470 while (true) { 1442 while (object->IsJSObject() &&
1471 real_holder->LocalLookup(*name, &lookup); 1443 JSObject::cast(object)->map()->is_hidden_prototype()) {
1472 if (lookup.IsProperty()) { 1444 JSObject* raw_holder = JSObject::cast(object);
1473 // Determine if this is a redeclaration of something read-only. 1445 raw_holder->LocalLookup(*name, &lookup);
1474 if (lookup.IsReadOnly()) { 1446 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
1475 // If we found readonly property on one of hidden prototypes, 1447 HandleScope handle_scope(isolate);
1476 // just shadow it. 1448 Handle<JSObject> holder(raw_holder);
1477 if (real_holder != isolate->context()->global()) break; 1449 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
1478 return ThrowRedeclarationError(isolate, "const", name); 1450 // Update the raw pointer in case it's changed due to GC.
1479 } 1451 raw_holder = *holder;
1480 1452 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
1481 // Determine if this is a redeclaration of an intercepted read-only 1453 // Found an interceptor that's not read only.
1482 // property and figure out if the property exists at all. 1454 if (assign) {
1483 bool found = true; 1455 return raw_holder->SetProperty(
1484 PropertyType type = lookup.type(); 1456 &lookup, *name, args[2], attributes, strict_mode);
1485 if (type == INTERCEPTOR) { 1457 } else {
1486 HandleScope handle_scope(isolate); 1458 return isolate->heap()->undefined_value();
1487 Handle<JSObject> holder(real_holder);
1488 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
1489 real_holder = *holder;
1490 if (intercepted == ABSENT) {
1491 // The interceptor claims the property isn't there. We need to
1492 // make sure to introduce it.
1493 found = false;
1494 } else if ((intercepted & READ_ONLY) != 0) {
1495 // The property is present, but read-only. Since we're trying to
1496 // overwrite it with a variable declaration we must throw a
1497 // re-declaration error. However if we found readonly property
1498 // on one of hidden prototypes, just shadow it.
1499 if (real_holder != isolate->context()->global()) break;
1500 return ThrowRedeclarationError(isolate, "const", name);
1501 } 1459 }
1502 } 1460 }
1503
1504 if (found && !assign) {
1505 // The global property is there and we're not assigning any value
1506 // to it. Just return.
1507 return isolate->heap()->undefined_value();
1508 }
1509
1510 // Assign the value (or undefined) to the property.
1511 Object* value = (assign) ? args[2] : isolate->heap()->undefined_value();
1512 return real_holder->SetProperty(
1513 &lookup, *name, value, attributes, strict_mode);
1514 } 1461 }
1515 1462 object = raw_holder->GetPrototype();
1516 Object* proto = real_holder->GetPrototype();
1517 if (!proto->IsJSObject())
1518 break;
1519
1520 if (!JSObject::cast(proto)->map()->is_hidden_prototype())
1521 break;
1522
1523 real_holder = JSObject::cast(proto);
1524 } 1463 }
1525 1464
1465 // Reload global in case the loop above performed a GC.
1526 global = isolate->context()->global(); 1466 global = isolate->context()->global();
1527 if (assign) { 1467 if (assign) {
1528 return global->SetProperty(*name, args[2], attributes, strict_mode); 1468 return global->SetProperty(*name, args[2], attributes, strict_mode);
1529 } 1469 }
1530 return isolate->heap()->undefined_value(); 1470 return isolate->heap()->undefined_value();
1531 } 1471 }
1532 1472
1533 1473
1534 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) { 1474 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
1535 // All constants are declared with an initial value. The name 1475 // All constants are declared with an initial value. The name
(...skipping 17 matching lines...) Expand all
1553 // prototype chain (this rules out using SetProperty). 1493 // prototype chain (this rules out using SetProperty).
1554 // We use SetLocalPropertyIgnoreAttributes instead 1494 // We use SetLocalPropertyIgnoreAttributes instead
1555 LookupResult lookup; 1495 LookupResult lookup;
1556 global->LocalLookup(*name, &lookup); 1496 global->LocalLookup(*name, &lookup);
1557 if (!lookup.IsProperty()) { 1497 if (!lookup.IsProperty()) {
1558 return global->SetLocalPropertyIgnoreAttributes(*name, 1498 return global->SetLocalPropertyIgnoreAttributes(*name,
1559 *value, 1499 *value,
1560 attributes); 1500 attributes);
1561 } 1501 }
1562 1502
1563 // Determine if this is a redeclaration of something not
1564 // read-only. In case the result is hidden behind an interceptor we
1565 // need to ask it for the property attributes.
1566 if (!lookup.IsReadOnly()) { 1503 if (!lookup.IsReadOnly()) {
1567 if (lookup.type() != INTERCEPTOR) {
1568 return ThrowRedeclarationError(isolate, "var", name);
1569 }
1570
1571 PropertyAttributes intercepted = global->GetPropertyAttribute(*name);
1572
1573 // Throw re-declaration error if the intercepted property is present
1574 // but not read-only.
1575 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
1576 return ThrowRedeclarationError(isolate, "var", name);
1577 }
1578
1579 // Restore global object from context (in case of GC) and continue 1504 // Restore global object from context (in case of GC) and continue
1580 // with setting the value because the property is either absent or 1505 // with setting the value.
1581 // read-only. We also have to do redo the lookup.
1582 HandleScope handle_scope(isolate); 1506 HandleScope handle_scope(isolate);
1583 Handle<GlobalObject> global(isolate->context()->global()); 1507 Handle<GlobalObject> global(isolate->context()->global());
1584 1508
1585 // BUG 1213575: Handle the case where we have to set a read-only 1509 // BUG 1213575: Handle the case where we have to set a read-only
1586 // property through an interceptor and only do it if it's 1510 // property through an interceptor and only do it if it's
1587 // uninitialized, e.g. the hole. Nirk... 1511 // uninitialized, e.g. the hole. Nirk...
1588 // Passing non-strict mode because the property is writable. 1512 // Passing non-strict mode because the property is writable.
1589 RETURN_IF_EMPTY_HANDLE(isolate, 1513 RETURN_IF_EMPTY_HANDLE(isolate,
1590 SetProperty(global, 1514 SetProperty(global,
1591 name, 1515 name,
1592 value, 1516 value,
1593 attributes, 1517 attributes,
1594 kNonStrictMode)); 1518 kNonStrictMode));
1595 return *value; 1519 return *value;
1596 } 1520 }
1597 1521
1598 // Set the value, but only we're assigning the initial value to a 1522 // Set the value, but only if we're assigning the initial value to a
1599 // constant. For now, we determine this by checking if the 1523 // constant. For now, we determine this by checking if the
1600 // current value is the hole. 1524 // current value is the hole.
1601 // Strict mode handling not needed (const disallowed in strict mode). 1525 // Strict mode handling not needed (const is disallowed in strict mode).
1602 PropertyType type = lookup.type(); 1526 PropertyType type = lookup.type();
1603 if (type == FIELD) { 1527 if (type == FIELD) {
1604 FixedArray* properties = global->properties(); 1528 FixedArray* properties = global->properties();
1605 int index = lookup.GetFieldIndex(); 1529 int index = lookup.GetFieldIndex();
1606 if (properties->get(index)->IsTheHole()) { 1530 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
1607 properties->set(index, *value); 1531 properties->set(index, *value);
1608 } 1532 }
1609 } else if (type == NORMAL) { 1533 } else if (type == NORMAL) {
1610 if (global->GetNormalizedProperty(&lookup)->IsTheHole()) { 1534 if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
1535 !lookup.IsReadOnly()) {
1611 global->SetNormalizedProperty(&lookup, *value); 1536 global->SetNormalizedProperty(&lookup, *value);
1612 } 1537 }
1613 } else { 1538 } else {
1614 // Ignore re-initialization of constants that have already been 1539 // Ignore re-initialization of constants that have already been
1615 // assigned a function value. 1540 // assigned a function value.
1616 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); 1541 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION);
1617 } 1542 }
1618 1543
1619 // Use the set value as the result of the operation. 1544 // Use the set value as the result of the operation.
1620 return *value; 1545 return *value;
1621 } 1546 }
1622 1547
1623 1548
1624 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { 1549 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1625 HandleScope scope(isolate); 1550 HandleScope scope(isolate);
1626 ASSERT(args.length() == 3); 1551 ASSERT(args.length() == 3);
1627 1552
1628 Handle<Object> value(args[0], isolate); 1553 Handle<Object> value(args[0], isolate);
1629 ASSERT(!value->IsTheHole()); 1554 ASSERT(!value->IsTheHole());
1630 CONVERT_ARG_CHECKED(Context, context, 1);
1631 Handle<String> name(String::cast(args[2]));
1632 1555
1633 // Initializations are always done in a function or global context. 1556 // Initializations are always done in a function or global context.
1634 context = Handle<Context>(context->declaration_context()); 1557 RUNTIME_ASSERT(args[1]->IsContext());
1558 Handle<Context> context(Context::cast(args[1])->declaration_context());
1559
1560 Handle<String> name(String::cast(args[2]));
1635 1561
1636 int index; 1562 int index;
1637 PropertyAttributes attributes; 1563 PropertyAttributes attributes;
1638 ContextLookupFlags flags = FOLLOW_CHAINS; 1564 ContextLookupFlags flags = FOLLOW_CHAINS;
1639 BindingFlags binding_flags; 1565 BindingFlags binding_flags;
1640 Handle<Object> holder = 1566 Handle<Object> holder =
1641 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1567 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1642 1568
1643 // In most situations, the property introduced by the const
1644 // declaration should be present in the context extension object.
1645 // However, because declaration and initialization are separate, the
1646 // property might have been deleted (if it was introduced by eval)
1647 // before we reach the initialization point.
1648 //
1649 // Example:
1650 //
1651 // function f() { eval("delete x; const x;"); }
1652 //
1653 // In that case, the initialization behaves like a normal assignment
1654 // to property 'x'.
1655 if (index >= 0) { 1569 if (index >= 0) {
1656 if (holder->IsContext()) { 1570 ASSERT(holder->IsContext());
1657 // Property was found in a context. Perform the assignment if we 1571 // Property was found in a context. Perform the assignment if we
1658 // found some non-constant or an uninitialized constant. 1572 // found some non-constant or an uninitialized constant.
1659 Handle<Context> context = Handle<Context>::cast(holder); 1573 Handle<Context> context = Handle<Context>::cast(holder);
1660 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) { 1574 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1661 context->set(index, *value); 1575 context->set(index, *value);
1662 }
1663 } else {
1664 // The holder is an arguments object.
1665 ASSERT((attributes & READ_ONLY) == 0);
1666 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1667 RETURN_IF_EMPTY_HANDLE(
1668 isolate,
1669 SetElement(arguments, index, value, kNonStrictMode));
1670 } 1576 }
1671 return *value; 1577 return *value;
1672 } 1578 }
1673 1579
1674 // The property could not be found, we introduce it in the global 1580 // The property could not be found, we introduce it as a property of the
1675 // context. 1581 // global object.
1676 if (attributes == ABSENT) { 1582 if (attributes == ABSENT) {
1677 Handle<JSObject> global = Handle<JSObject>( 1583 Handle<JSObject> global = Handle<JSObject>(
1678 isolate->context()->global()); 1584 isolate->context()->global());
1679 // Strict mode not needed (const disallowed in strict mode). 1585 // Strict mode not needed (const disallowed in strict mode).
1680 RETURN_IF_EMPTY_HANDLE( 1586 RETURN_IF_EMPTY_HANDLE(
1681 isolate, 1587 isolate,
1682 SetProperty(global, name, value, NONE, kNonStrictMode)); 1588 SetProperty(global, name, value, NONE, kNonStrictMode));
1683 return *value; 1589 return *value;
1684 } 1590 }
1685 1591
1686 // The property was present in a context extension object. 1592 // The property was present in some function's context extension object,
1687 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1593 // as a property on the subject of a with, or as a property of the global
1594 // object.
1595 //
1596 // In most situations, eval-introduced consts should still be present in
1597 // the context extension object. However, because declaration and
1598 // initialization are separate, the property might have been deleted
1599 // before we reach the initialization point.
1600 //
1601 // Example:
1602 //
1603 // function f() { eval("delete x; const x;"); }
1604 //
1605 // In that case, the initialization behaves like a normal assignment.
1606 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1688 1607
1689 if (*context_ext == context->extension()) { 1608 if (*object == context->extension()) {
1690 // This is the property that was introduced by the const 1609 // This is the property that was introduced by the const declaration.
1691 // declaration. Set it if it hasn't been set before. NOTE: We 1610 // Set it if it hasn't been set before. NOTE: We cannot use
1692 // cannot use GetProperty() to get the current value as it 1611 // GetProperty() to get the current value as it 'unholes' the value.
1693 // 'unholes' the value.
1694 LookupResult lookup; 1612 LookupResult lookup;
1695 context_ext->LocalLookupRealNamedProperty(*name, &lookup); 1613 object->LocalLookupRealNamedProperty(*name, &lookup);
1696 ASSERT(lookup.IsProperty()); // the property was declared 1614 ASSERT(lookup.IsProperty()); // the property was declared
1697 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only 1615 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
1698 1616
1699 PropertyType type = lookup.type(); 1617 PropertyType type = lookup.type();
1700 if (type == FIELD) { 1618 if (type == FIELD) {
1701 FixedArray* properties = context_ext->properties(); 1619 FixedArray* properties = object->properties();
1702 int index = lookup.GetFieldIndex(); 1620 int index = lookup.GetFieldIndex();
1703 if (properties->get(index)->IsTheHole()) { 1621 if (properties->get(index)->IsTheHole()) {
1704 properties->set(index, *value); 1622 properties->set(index, *value);
1705 } 1623 }
1706 } else if (type == NORMAL) { 1624 } else if (type == NORMAL) {
1707 if (context_ext->GetNormalizedProperty(&lookup)->IsTheHole()) { 1625 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
1708 context_ext->SetNormalizedProperty(&lookup, *value); 1626 object->SetNormalizedProperty(&lookup, *value);
1709 } 1627 }
1710 } else { 1628 } else {
1711 // We should not reach here. Any real, named property should be 1629 // We should not reach here. Any real, named property should be
1712 // either a field or a dictionary slot. 1630 // either a field or a dictionary slot.
1713 UNREACHABLE(); 1631 UNREACHABLE();
1714 } 1632 }
1715 } else { 1633 } else {
1716 // The property was found in a different context extension object. 1634 // The property was found on some other object. Set it if it is not a
1717 // Set it if it is not a read-only property. 1635 // read-only property.
1718 if ((attributes & READ_ONLY) == 0) { 1636 if ((attributes & READ_ONLY) == 0) {
1719 // Strict mode not needed (const disallowed in strict mode). 1637 // Strict mode not needed (const disallowed in strict mode).
1720 RETURN_IF_EMPTY_HANDLE( 1638 RETURN_IF_EMPTY_HANDLE(
1721 isolate, 1639 isolate,
1722 SetProperty(context_ext, name, value, attributes, kNonStrictMode)); 1640 SetProperty(object, name, value, attributes, kNonStrictMode));
1723 } 1641 }
1724 } 1642 }
1725 1643
1726 return *value; 1644 return *value;
1727 } 1645 }
1728 1646
1729 1647
1730 RUNTIME_FUNCTION(MaybeObject*, 1648 RUNTIME_FUNCTION(MaybeObject*,
1731 Runtime_OptimizeObjectForAddingMultipleProperties) { 1649 Runtime_OptimizeObjectForAddingMultipleProperties) {
1732 HandleScope scope(isolate); 1650 HandleScope scope(isolate);
1733 ASSERT(args.length() == 2); 1651 ASSERT(args.length() == 2);
1734 CONVERT_ARG_CHECKED(JSObject, object, 0); 1652 CONVERT_ARG_CHECKED(JSObject, object, 0);
1735 CONVERT_SMI_ARG_CHECKED(properties, 1); 1653 CONVERT_SMI_ARG_CHECKED(properties, 1);
1736 if (object->HasFastProperties()) { 1654 if (object->HasFastProperties()) {
1737 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); 1655 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1738 } 1656 }
1739 return *object; 1657 return *object;
1740 } 1658 }
1741 1659
1742 1660
1661 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
1662 ASSERT(args.length() == 1);
1663 CONVERT_ARG_CHECKED(JSObject, object, 0);
1664 if (FLAG_smi_only_arrays && object->HasFastSmiOnlyElements()) {
1665 MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
1666 Map* map;
1667 if (!maybe_map->To<Map>(&map)) return maybe_map;
1668 object->set_map(Map::cast(map));
1669 }
1670 return *object;
1671 }
1672
1673
1743 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { 1674 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1744 HandleScope scope(isolate); 1675 HandleScope scope(isolate);
1745 ASSERT(args.length() == 4); 1676 ASSERT(args.length() == 4);
1746 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 1677 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
1747 CONVERT_ARG_CHECKED(String, subject, 1); 1678 CONVERT_ARG_CHECKED(String, subject, 1);
1748 // Due to the way the JS calls are constructed this must be less than the 1679 // Due to the way the JS calls are constructed this must be less than the
1749 // length of a string, i.e. it is always a Smi. We check anyway for security. 1680 // length of a string, i.e. it is always a Smi. We check anyway for security.
1750 CONVERT_SMI_ARG_CHECKED(index, 2); 1681 CONVERT_SMI_ARG_CHECKED(index, 2);
1751 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 1682 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1752 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1683 RUNTIME_ASSERT(last_match_info->HasFastElements());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 JSFunction::cast(constructor)->initial_map() == map) { 1749 JSFunction::cast(constructor)->initial_map() == map) {
1819 // If we still have the original map, set in-object properties directly. 1750 // If we still have the original map, set in-object properties directly.
1820 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); 1751 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
1821 // TODO(lrn): Consider skipping write barrier on booleans as well. 1752 // TODO(lrn): Consider skipping write barrier on booleans as well.
1822 // Both true and false should be in oldspace at all times. 1753 // Both true and false should be in oldspace at all times.
1823 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); 1754 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global);
1824 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); 1755 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase);
1825 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); 1756 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline);
1826 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, 1757 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1827 Smi::FromInt(0), 1758 Smi::FromInt(0),
1828 SKIP_WRITE_BARRIER); 1759 SKIP_WRITE_BARRIER); // It's a Smi.
1829 return regexp; 1760 return regexp;
1830 } 1761 }
1831 1762
1832 // Map has changed, so use generic, but slower, method. 1763 // Map has changed, so use generic, but slower, method.
1833 PropertyAttributes final = 1764 PropertyAttributes final =
1834 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); 1765 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
1835 PropertyAttributes writable = 1766 PropertyAttributes writable =
1836 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 1767 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1837 Heap* heap = isolate->heap(); 1768 Heap* heap = isolate->heap();
1838 MaybeObject* result; 1769 MaybeObject* result;
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 int number_of_literals = fun->NumberOfLiterals(); 2163 int number_of_literals = fun->NumberOfLiterals();
2233 Handle<FixedArray> literals = 2164 Handle<FixedArray> literals =
2234 isolate->factory()->NewFixedArray(number_of_literals, TENURED); 2165 isolate->factory()->NewFixedArray(number_of_literals, TENURED);
2235 if (number_of_literals > 0) { 2166 if (number_of_literals > 0) {
2236 // Insert the object, regexp and array functions in the literals 2167 // Insert the object, regexp and array functions in the literals
2237 // array prefix. These are the functions that will be used when 2168 // array prefix. These are the functions that will be used when
2238 // creating object, regexp and array literals. 2169 // creating object, regexp and array literals.
2239 literals->set(JSFunction::kLiteralGlobalContextIndex, 2170 literals->set(JSFunction::kLiteralGlobalContextIndex,
2240 context->global_context()); 2171 context->global_context());
2241 } 2172 }
2242 // It's okay to skip the write barrier here because the literals 2173 target->set_literals(*literals);
2243 // are guaranteed to be in old space.
2244 target->set_literals(*literals, SKIP_WRITE_BARRIER);
2245 target->set_next_function_link(isolate->heap()->undefined_value()); 2174 target->set_next_function_link(isolate->heap()->undefined_value());
2246 2175
2247 if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { 2176 if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
2248 isolate->logger()->LogExistingFunction( 2177 isolate->logger()->LogExistingFunction(
2249 shared, Handle<Code>(shared->code())); 2178 shared, Handle<Code>(shared->code()));
2250 } 2179 }
2251 } 2180 }
2252 2181
2253 target->set_context(*context); 2182 target->set_context(*context);
2254 return *target; 2183 return *target;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 NoHandleAllocation ha; 2247 NoHandleAllocation ha;
2319 ASSERT(args.length() == 1); 2248 ASSERT(args.length() == 1);
2320 return CharFromCode(isolate, args[0]); 2249 return CharFromCode(isolate, args[0]);
2321 } 2250 }
2322 2251
2323 2252
2324 class FixedArrayBuilder { 2253 class FixedArrayBuilder {
2325 public: 2254 public:
2326 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) 2255 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
2327 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), 2256 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
2328 length_(0) { 2257 length_(0),
2258 has_non_smi_elements_(false) {
2329 // Require a non-zero initial size. Ensures that doubling the size to 2259 // Require a non-zero initial size. Ensures that doubling the size to
2330 // extend the array will work. 2260 // extend the array will work.
2331 ASSERT(initial_capacity > 0); 2261 ASSERT(initial_capacity > 0);
2332 } 2262 }
2333 2263
2334 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) 2264 explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
2335 : array_(backing_store), 2265 : array_(backing_store),
2336 length_(0) { 2266 length_(0),
2267 has_non_smi_elements_(false) {
2337 // Require a non-zero initial size. Ensures that doubling the size to 2268 // Require a non-zero initial size. Ensures that doubling the size to
2338 // extend the array will work. 2269 // extend the array will work.
2339 ASSERT(backing_store->length() > 0); 2270 ASSERT(backing_store->length() > 0);
2340 } 2271 }
2341 2272
2342 bool HasCapacity(int elements) { 2273 bool HasCapacity(int elements) {
2343 int length = array_->length(); 2274 int length = array_->length();
2344 int required_length = length_ + elements; 2275 int required_length = length_ + elements;
2345 return (length >= required_length); 2276 return (length >= required_length);
2346 } 2277 }
2347 2278
2348 void EnsureCapacity(int elements) { 2279 void EnsureCapacity(int elements) {
2349 int length = array_->length(); 2280 int length = array_->length();
2350 int required_length = length_ + elements; 2281 int required_length = length_ + elements;
2351 if (length < required_length) { 2282 if (length < required_length) {
2352 int new_length = length; 2283 int new_length = length;
2353 do { 2284 do {
2354 new_length *= 2; 2285 new_length *= 2;
2355 } while (new_length < required_length); 2286 } while (new_length < required_length);
2356 Handle<FixedArray> extended_array = 2287 Handle<FixedArray> extended_array =
2357 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); 2288 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
2358 array_->CopyTo(0, *extended_array, 0, length_); 2289 array_->CopyTo(0, *extended_array, 0, length_);
2359 array_ = extended_array; 2290 array_ = extended_array;
2360 } 2291 }
2361 } 2292 }
2362 2293
2363 void Add(Object* value) { 2294 void Add(Object* value) {
2295 ASSERT(!value->IsSmi());
2364 ASSERT(length_ < capacity()); 2296 ASSERT(length_ < capacity());
2365 array_->set(length_, value); 2297 array_->set(length_, value);
2366 length_++; 2298 length_++;
2299 has_non_smi_elements_ = true;
2367 } 2300 }
2368 2301
2369 void Add(Smi* value) { 2302 void Add(Smi* value) {
2303 ASSERT(value->IsSmi());
2370 ASSERT(length_ < capacity()); 2304 ASSERT(length_ < capacity());
2371 array_->set(length_, value); 2305 array_->set(length_, value);
2372 length_++; 2306 length_++;
2373 } 2307 }
2374 2308
2375 Handle<FixedArray> array() { 2309 Handle<FixedArray> array() {
2376 return array_; 2310 return array_;
2377 } 2311 }
2378 2312
2379 int length() { 2313 int length() {
2380 return length_; 2314 return length_;
2381 } 2315 }
2382 2316
2383 int capacity() { 2317 int capacity() {
2384 return array_->length(); 2318 return array_->length();
2385 } 2319 }
2386 2320
2387 Handle<JSArray> ToJSArray() { 2321 Handle<JSArray> ToJSArray() {
2388 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); 2322 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_);
2389 result_array->set_length(Smi::FromInt(length_)); 2323 result_array->set_length(Smi::FromInt(length_));
2390 return result_array; 2324 return result_array;
2391 } 2325 }
2392 2326
2393 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { 2327 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
2394 target_array->set_elements(*array_); 2328 FACTORY->SetContent(target_array, array_);
2395 target_array->set_length(Smi::FromInt(length_)); 2329 target_array->set_length(Smi::FromInt(length_));
2396 return target_array; 2330 return target_array;
2397 } 2331 }
2398 2332
2399 private: 2333 private:
2400 Handle<FixedArray> array_; 2334 Handle<FixedArray> array_;
2401 int length_; 2335 int length_;
2336 bool has_non_smi_elements_;
2402 }; 2337 };
2403 2338
2404 2339
2405 // Forward declarations. 2340 // Forward declarations.
2406 const int kStringBuilderConcatHelperLengthBits = 11; 2341 const int kStringBuilderConcatHelperLengthBits = 11;
2407 const int kStringBuilderConcatHelperPositionBits = 19; 2342 const int kStringBuilderConcatHelperPositionBits = 19;
2408 2343
2409 template <typename schar> 2344 template <typename schar>
2410 static inline void StringBuilderConcatHelper(String*, 2345 static inline void StringBuilderConcatHelper(String*,
2411 schar*, 2346 schar*,
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 } 2821 }
2887 } else { 2822 } else {
2888 FindStringIndices(isolate, 2823 FindStringIndices(isolate,
2889 subject_vector, 2824 subject_vector,
2890 pattern_content.ToUC16Vector(), 2825 pattern_content.ToUC16Vector(),
2891 indices, 2826 indices,
2892 limit); 2827 limit);
2893 } 2828 }
2894 } else { 2829 } else {
2895 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); 2830 Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
2896 if (pattern->IsAsciiRepresentation()) { 2831 if (pattern_content.IsAscii()) {
2897 FindStringIndices(isolate, 2832 FindStringIndices(isolate,
2898 subject_vector, 2833 subject_vector,
2899 pattern_content.ToAsciiVector(), 2834 pattern_content.ToAsciiVector(),
2900 indices, 2835 indices,
2901 limit); 2836 limit);
2902 } else { 2837 } else {
2903 FindStringIndices(isolate, 2838 FindStringIndices(isolate,
2904 subject_vector, 2839 subject_vector,
2905 pattern_content.ToUC16Vector(), 2840 pattern_content.ToUC16Vector(),
2906 indices, 2841 indices,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
3012 ZoneScope zone(isolate, DELETE_ON_EXIT); 2947 ZoneScope zone(isolate, DELETE_ON_EXIT);
3013 CompiledReplacement compiled_replacement; 2948 CompiledReplacement compiled_replacement;
3014 compiled_replacement.Compile(replacement_handle, 2949 compiled_replacement.Compile(replacement_handle,
3015 capture_count, 2950 capture_count,
3016 length); 2951 length);
3017 2952
3018 bool is_global = regexp_handle->GetFlags().is_global(); 2953 bool is_global = regexp_handle->GetFlags().is_global();
3019 2954
3020 // Shortcut for simple non-regexp global replacements 2955 // Shortcut for simple non-regexp global replacements
3021 if (is_global && 2956 if (is_global &&
3022 regexp->TypeTag() == JSRegExp::ATOM && 2957 regexp_handle->TypeTag() == JSRegExp::ATOM &&
3023 compiled_replacement.simple_hint()) { 2958 compiled_replacement.simple_hint()) {
3024 if (subject_handle->HasOnlyAsciiChars() && 2959 if (subject_handle->HasOnlyAsciiChars() &&
3025 replacement_handle->HasOnlyAsciiChars()) { 2960 replacement_handle->HasOnlyAsciiChars()) {
3026 return StringReplaceStringWithString<SeqAsciiString>( 2961 return StringReplaceStringWithString<SeqAsciiString>(
3027 isolate, subject_handle, regexp_handle, replacement_handle); 2962 isolate, subject_handle, regexp_handle, replacement_handle);
3028 } else { 2963 } else {
3029 return StringReplaceStringWithString<SeqTwoByteString>( 2964 return StringReplaceStringWithString<SeqTwoByteString>(
3030 isolate, subject_handle, regexp_handle, replacement_handle); 2965 isolate, subject_handle, regexp_handle, replacement_handle);
3031 } 2966 }
3032 } 2967 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 // Shorten string and fill 3170 // Shorten string and fill
3236 int string_size = ResultSeqString::SizeFor(position); 3171 int string_size = ResultSeqString::SizeFor(position);
3237 int allocated_string_size = ResultSeqString::SizeFor(new_length); 3172 int allocated_string_size = ResultSeqString::SizeFor(new_length);
3238 int delta = allocated_string_size - string_size; 3173 int delta = allocated_string_size - string_size;
3239 3174
3240 answer->set_length(position); 3175 answer->set_length(position);
3241 if (delta == 0) return *answer; 3176 if (delta == 0) return *answer;
3242 3177
3243 Address end_of_string = answer->address() + string_size; 3178 Address end_of_string = answer->address() + string_size;
3244 isolate->heap()->CreateFillerObjectAt(end_of_string, delta); 3179 isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
3180 if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
3181 MemoryChunk::IncrementLiveBytes(answer->address(), -delta);
3182 }
3245 3183
3246 return *answer; 3184 return *answer;
3247 } 3185 }
3248 3186
3249 3187
3250 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { 3188 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) {
3251 ASSERT(args.length() == 4); 3189 ASSERT(args.length() == 4);
3252 3190
3253 CONVERT_CHECKED(String, subject, args[0]); 3191 CONVERT_CHECKED(String, subject, args[0]);
3254 if (!subject->IsFlat()) { 3192 if (!subject->IsFlat()) {
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 // Character array used for conversion. 3932 // Character array used for conversion.
3995 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 3933 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
3996 return isolate->heap()-> 3934 return isolate->heap()->
3997 LookupSingleCharacterStringFromCode(kCharTable[value]); 3935 LookupSingleCharacterStringFromCode(kCharTable[value]);
3998 } 3936 }
3999 } 3937 }
4000 3938
4001 // Slow case. 3939 // Slow case.
4002 CONVERT_DOUBLE_ARG_CHECKED(value, 0); 3940 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4003 if (isnan(value)) { 3941 if (isnan(value)) {
4004 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3942 return *isolate->factory()->nan_symbol();
4005 } 3943 }
4006 if (isinf(value)) { 3944 if (isinf(value)) {
4007 if (value < 0) { 3945 if (value < 0) {
4008 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3946 return *isolate->factory()->minus_infinity_symbol();
4009 } 3947 }
4010 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3948 return *isolate->factory()->infinity_symbol();
4011 } 3949 }
4012 char* str = DoubleToRadixCString(value, radix); 3950 char* str = DoubleToRadixCString(value, radix);
4013 MaybeObject* result = 3951 MaybeObject* result =
4014 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3952 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
4015 DeleteArray(str); 3953 DeleteArray(str);
4016 return result; 3954 return result;
4017 } 3955 }
4018 3956
4019 3957
4020 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) { 3958 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
4021 NoHandleAllocation ha; 3959 NoHandleAllocation ha;
4022 ASSERT(args.length() == 2); 3960 ASSERT(args.length() == 2);
4023 3961
4024 CONVERT_DOUBLE_ARG_CHECKED(value, 0); 3962 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4025 if (isnan(value)) { 3963 if (isnan(value)) {
4026 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3964 return *isolate->factory()->nan_symbol();
4027 } 3965 }
4028 if (isinf(value)) { 3966 if (isinf(value)) {
4029 if (value < 0) { 3967 if (value < 0) {
4030 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3968 return *isolate->factory()->minus_infinity_symbol();
4031 } 3969 }
4032 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3970 return *isolate->factory()->infinity_symbol();
4033 } 3971 }
4034 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); 3972 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4035 int f = FastD2I(f_number); 3973 int f = FastD2I(f_number);
4036 RUNTIME_ASSERT(f >= 0); 3974 RUNTIME_ASSERT(f >= 0);
4037 char* str = DoubleToFixedCString(value, f); 3975 char* str = DoubleToFixedCString(value, f);
4038 MaybeObject* res = 3976 MaybeObject* res =
4039 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3977 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
4040 DeleteArray(str); 3978 DeleteArray(str);
4041 return res; 3979 return res;
4042 } 3980 }
4043 3981
4044 3982
4045 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) { 3983 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
4046 NoHandleAllocation ha; 3984 NoHandleAllocation ha;
4047 ASSERT(args.length() == 2); 3985 ASSERT(args.length() == 2);
4048 3986
4049 CONVERT_DOUBLE_ARG_CHECKED(value, 0); 3987 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4050 if (isnan(value)) { 3988 if (isnan(value)) {
4051 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3989 return *isolate->factory()->nan_symbol();
4052 } 3990 }
4053 if (isinf(value)) { 3991 if (isinf(value)) {
4054 if (value < 0) { 3992 if (value < 0) {
4055 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3993 return *isolate->factory()->minus_infinity_symbol();
4056 } 3994 }
4057 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3995 return *isolate->factory()->infinity_symbol();
4058 } 3996 }
4059 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); 3997 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4060 int f = FastD2I(f_number); 3998 int f = FastD2I(f_number);
4061 RUNTIME_ASSERT(f >= -1 && f <= 20); 3999 RUNTIME_ASSERT(f >= -1 && f <= 20);
4062 char* str = DoubleToExponentialCString(value, f); 4000 char* str = DoubleToExponentialCString(value, f);
4063 MaybeObject* res = 4001 MaybeObject* res =
4064 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 4002 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
4065 DeleteArray(str); 4003 DeleteArray(str);
4066 return res; 4004 return res;
4067 } 4005 }
4068 4006
4069 4007
4070 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) { 4008 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
4071 NoHandleAllocation ha; 4009 NoHandleAllocation ha;
4072 ASSERT(args.length() == 2); 4010 ASSERT(args.length() == 2);
4073 4011
4074 CONVERT_DOUBLE_ARG_CHECKED(value, 0); 4012 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4075 if (isnan(value)) { 4013 if (isnan(value)) {
4076 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 4014 return *isolate->factory()->nan_symbol();
4077 } 4015 }
4078 if (isinf(value)) { 4016 if (isinf(value)) {
4079 if (value < 0) { 4017 if (value < 0) {
4080 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 4018 return *isolate->factory()->minus_infinity_symbol();
4081 } 4019 }
4082 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 4020 return *isolate->factory()->infinity_symbol();
4083 } 4021 }
4084 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); 4022 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4085 int f = FastD2I(f_number); 4023 int f = FastD2I(f_number);
4086 RUNTIME_ASSERT(f >= 1 && f <= 21); 4024 RUNTIME_ASSERT(f >= 1 && f <= 21);
4087 char* str = DoubleToPrecisionCString(value, f); 4025 char* str = DoubleToPrecisionCString(value, f);
4088 MaybeObject* res = 4026 MaybeObject* res =
4089 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 4027 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
4090 DeleteArray(str); 4028 DeleteArray(str);
4091 return res; 4029 return res;
4092 } 4030 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4262 // Steps 9c & 12 - replace an existing data property with an accessor property. 4200 // Steps 9c & 12 - replace an existing data property with an accessor property.
4263 // Step 12 - update an existing accessor property with an accessor or generic 4201 // Step 12 - update an existing accessor property with an accessor or generic
4264 // descriptor. 4202 // descriptor.
4265 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { 4203 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
4266 ASSERT(args.length() == 5); 4204 ASSERT(args.length() == 5);
4267 HandleScope scope(isolate); 4205 HandleScope scope(isolate);
4268 CONVERT_ARG_CHECKED(JSObject, obj, 0); 4206 CONVERT_ARG_CHECKED(JSObject, obj, 0);
4269 CONVERT_CHECKED(String, name, args[1]); 4207 CONVERT_CHECKED(String, name, args[1]);
4270 CONVERT_CHECKED(Smi, flag_setter, args[2]); 4208 CONVERT_CHECKED(Smi, flag_setter, args[2]);
4271 Object* fun = args[3]; 4209 Object* fun = args[3];
4272 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); 4210 RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined());
4273 CONVERT_CHECKED(Smi, flag_attr, args[4]); 4211 CONVERT_CHECKED(Smi, flag_attr, args[4]);
4274 int unchecked = flag_attr->value(); 4212 int unchecked = flag_attr->value();
4275 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4213 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4276 RUNTIME_ASSERT(!obj->IsNull()); 4214 RUNTIME_ASSERT(!obj->IsNull());
4277 LookupResult result; 4215 LookupResult result;
4278 obj->LocalLookupRealNamedProperty(name, &result); 4216 obj->LocalLookupRealNamedProperty(name, &result);
4279 4217
4280 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4218 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4281 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION 4219 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
4282 // delete it to avoid running into trouble in DefineAccessor, which 4220 // delete it to avoid running into trouble in DefineAccessor, which
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4430 HandleScope scope(isolate); 4368 HandleScope scope(isolate);
4431 4369
4432 if (object->IsUndefined() || object->IsNull()) { 4370 if (object->IsUndefined() || object->IsNull()) {
4433 Handle<Object> args[2] = { key, object }; 4371 Handle<Object> args[2] = { key, object };
4434 Handle<Object> error = 4372 Handle<Object> error =
4435 isolate->factory()->NewTypeError("non_object_property_store", 4373 isolate->factory()->NewTypeError("non_object_property_store",
4436 HandleVector(args, 2)); 4374 HandleVector(args, 2));
4437 return isolate->Throw(*error); 4375 return isolate->Throw(*error);
4438 } 4376 }
4439 4377
4378 if (object->IsJSProxy()) {
4379 bool has_pending_exception = false;
4380 Handle<Object> name = Execution::ToString(key, &has_pending_exception);
4381 if (has_pending_exception) return Failure::Exception();
4382 return JSProxy::cast(*object)->SetProperty(
4383 String::cast(*name), *value, attr, strict_mode);
4384 }
4385
4440 // If the object isn't a JavaScript object, we ignore the store. 4386 // If the object isn't a JavaScript object, we ignore the store.
4441 if (!object->IsJSObject()) return *value; 4387 if (!object->IsJSObject()) return *value;
4442 4388
4443 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 4389 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
4444 4390
4445 // Check if the given key is an array index. 4391 // Check if the given key is an array index.
4446 uint32_t index; 4392 uint32_t index;
4447 if (key->ToArrayIndex(&index)) { 4393 if (key->ToArrayIndex(&index)) {
4448 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 4394 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
4449 // of a string using [] notation. We need to support this too in 4395 // of a string using [] notation. We need to support this too in
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4549 } 4495 }
4550 4496
4551 4497
4552 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate, 4498 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4553 Handle<JSReceiver> receiver, 4499 Handle<JSReceiver> receiver,
4554 Handle<Object> key) { 4500 Handle<Object> key) {
4555 HandleScope scope(isolate); 4501 HandleScope scope(isolate);
4556 4502
4557 // Check if the given key is an array index. 4503 // Check if the given key is an array index.
4558 uint32_t index; 4504 uint32_t index;
4559 if (receiver->IsJSObject() && key->ToArrayIndex(&index)) { 4505 if (key->ToArrayIndex(&index)) {
4560 // In Firefox/SpiderMonkey, Safari and Opera you can access the 4506 // In Firefox/SpiderMonkey, Safari and Opera you can access the
4561 // characters of a string using [] notation. In the case of a 4507 // characters of a string using [] notation. In the case of a
4562 // String object we just need to redirect the deletion to the 4508 // String object we just need to redirect the deletion to the
4563 // underlying string if the index is in range. Since the 4509 // underlying string if the index is in range. Since the
4564 // underlying string does nothing with the deletion, we can ignore 4510 // underlying string does nothing with the deletion, we can ignore
4565 // such deletions. 4511 // such deletions.
4566 if (receiver->IsStringObjectWithCharacterAt(index)) { 4512 if (receiver->IsStringObjectWithCharacterAt(index)) {
4567 return isolate->heap()->true_value(); 4513 return isolate->heap()->true_value();
4568 } 4514 }
4569 4515
4570 return JSObject::cast(*receiver)->DeleteElement( 4516 return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION);
4571 index, JSReceiver::FORCE_DELETION);
4572 } 4517 }
4573 4518
4574 Handle<String> key_string; 4519 Handle<String> key_string;
4575 if (key->IsString()) { 4520 if (key->IsString()) {
4576 key_string = Handle<String>::cast(key); 4521 key_string = Handle<String>::cast(key);
4577 } else { 4522 } else {
4578 // Call-back into JavaScript to convert the key to a string. 4523 // Call-back into JavaScript to convert the key to a string.
4579 bool has_pending_exception = false; 4524 bool has_pending_exception = false;
4580 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4525 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
4581 if (has_pending_exception) return Failure::Exception(); 4526 if (has_pending_exception) return Failure::Exception();
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
4723 return isolate->heap()->true_value(); 4668 return isolate->heap()->true_value();
4724 } 4669 }
4725 } 4670 }
4726 return isolate->heap()->false_value(); 4671 return isolate->heap()->false_value();
4727 } 4672 }
4728 4673
4729 4674
4730 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { 4675 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
4731 NoHandleAllocation na; 4676 NoHandleAllocation na;
4732 ASSERT(args.length() == 2); 4677 ASSERT(args.length() == 2);
4678 CONVERT_CHECKED(JSReceiver, receiver, args[0]);
4679 CONVERT_CHECKED(String, key, args[1]);
4733 4680
4734 // Only JS receivers can have properties. 4681 bool result = receiver->HasProperty(key);
4735 if (args[0]->IsJSReceiver()) { 4682 if (isolate->has_pending_exception()) return Failure::Exception();
4736 JSReceiver* receiver = JSReceiver::cast(args[0]); 4683 return isolate->heap()->ToBoolean(result);
4737 CONVERT_CHECKED(String, key, args[1]);
4738 if (receiver->HasProperty(key)) return isolate->heap()->true_value();
4739 }
4740 return isolate->heap()->false_value();
4741 } 4684 }
4742 4685
4743 4686
4744 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { 4687 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
4745 NoHandleAllocation na; 4688 NoHandleAllocation na;
4746 ASSERT(args.length() == 2); 4689 ASSERT(args.length() == 2);
4690 CONVERT_CHECKED(JSReceiver, receiver, args[0]);
4691 CONVERT_CHECKED(Smi, index, args[1]);
4747 4692
4748 // Only JS objects can have elements. 4693 bool result = receiver->HasElement(index->value());
4749 if (args[0]->IsJSObject()) { 4694 if (isolate->has_pending_exception()) return Failure::Exception();
4750 JSObject* object = JSObject::cast(args[0]); 4695 return isolate->heap()->ToBoolean(result);
4751 CONVERT_CHECKED(Smi, index_obj, args[1]);
4752 uint32_t index = index_obj->value();
4753 if (object->HasElement(index)) return isolate->heap()->true_value();
4754 }
4755 return isolate->heap()->false_value();
4756 } 4696 }
4757 4697
4758 4698
4759 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { 4699 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
4760 NoHandleAllocation ha; 4700 NoHandleAllocation ha;
4761 ASSERT(args.length() == 2); 4701 ASSERT(args.length() == 2);
4762 4702
4763 CONVERT_CHECKED(JSObject, object, args[0]); 4703 CONVERT_CHECKED(JSObject, object, args[0]);
4764 CONVERT_CHECKED(String, key, args[1]); 4704 CONVERT_CHECKED(String, key, args[1]);
4765 4705
4766 uint32_t index; 4706 uint32_t index;
4767 if (key->AsArrayIndex(&index)) { 4707 if (key->AsArrayIndex(&index)) {
4768 return isolate->heap()->ToBoolean(object->HasElement(index)); 4708 JSObject::LocalElementType type = object->HasLocalElement(index);
4709 switch (type) {
4710 case JSObject::UNDEFINED_ELEMENT:
4711 case JSObject::STRING_CHARACTER_ELEMENT:
4712 return isolate->heap()->false_value();
4713 case JSObject::INTERCEPTED_ELEMENT:
4714 case JSObject::FAST_ELEMENT:
4715 return isolate->heap()->true_value();
4716 case JSObject::DICTIONARY_ELEMENT: {
4717 if (object->IsJSGlobalProxy()) {
4718 Object* proto = object->GetPrototype();
4719 if (proto->IsNull()) {
4720 return isolate->heap()->false_value();
4721 }
4722 ASSERT(proto->IsJSGlobalObject());
4723 object = JSObject::cast(proto);
4724 }
4725 FixedArray* elements = FixedArray::cast(object->elements());
4726 NumberDictionary* dictionary = NULL;
4727 if (elements->map() ==
4728 isolate->heap()->non_strict_arguments_elements_map()) {
4729 dictionary = NumberDictionary::cast(elements->get(1));
4730 } else {
4731 dictionary = NumberDictionary::cast(elements);
4732 }
4733 int entry = dictionary->FindEntry(index);
4734 ASSERT(entry != NumberDictionary::kNotFound);
4735 PropertyDetails details = dictionary->DetailsAt(entry);
4736 return isolate->heap()->ToBoolean(!details.IsDontEnum());
4737 }
4738 }
4769 } 4739 }
4770 4740
4771 PropertyAttributes att = object->GetLocalPropertyAttribute(key); 4741 PropertyAttributes att = object->GetLocalPropertyAttribute(key);
4772 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); 4742 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0);
4773 } 4743 }
4774 4744
4775 4745
4776 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { 4746 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
4777 HandleScope scope(isolate); 4747 HandleScope scope(isolate);
4778 ASSERT(args.length() == 1); 4748 ASSERT(args.length() == 1);
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
5572 } 5542 }
5573 MaybeObject* new_alloc = AllocateRawString<StringType>(isolate, 5543 MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
5574 quoted_length); 5544 quoted_length);
5575 Object* new_object; 5545 Object* new_object;
5576 if (!new_alloc->ToObject(&new_object)) { 5546 if (!new_alloc->ToObject(&new_object)) {
5577 return new_alloc; 5547 return new_alloc;
5578 } 5548 }
5579 StringType* new_string = StringType::cast(new_object); 5549 StringType* new_string = StringType::cast(new_object);
5580 5550
5581 Char* write_cursor = reinterpret_cast<Char*>( 5551 Char* write_cursor = reinterpret_cast<Char*>(
5582 new_string->address() + SeqAsciiString::kHeaderSize); 5552 new_string->address() + SeqString::kHeaderSize);
5583 if (comma) *(write_cursor++) = ','; 5553 if (comma) *(write_cursor++) = ',';
5584 *(write_cursor++) = '"'; 5554 *(write_cursor++) = '"';
5585 5555
5586 read_cursor = characters.start(); 5556 read_cursor = characters.start();
5587 while (read_cursor < end) { 5557 while (read_cursor < end) {
5588 Char c = *(read_cursor++); 5558 Char c = *(read_cursor++);
5589 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 5559 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
5590 *(write_cursor++) = c; 5560 *(write_cursor++) = c;
5591 } else { 5561 } else {
5592 int len = JsonQuoteLengths[static_cast<unsigned>(c)]; 5562 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 if (!isolate->heap()->new_space()->Contains(new_object)) { 5630 if (!isolate->heap()->new_space()->Contains(new_object)) {
5661 // Even if our string is small enough to fit in new space we still have to 5631 // Even if our string is small enough to fit in new space we still have to
5662 // handle it being allocated in old space as may happen in the third 5632 // handle it being allocated in old space as may happen in the third
5663 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in 5633 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5664 // CEntryStub::GenerateCore. 5634 // CEntryStub::GenerateCore.
5665 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters); 5635 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
5666 } 5636 }
5667 StringType* new_string = StringType::cast(new_object); 5637 StringType* new_string = StringType::cast(new_object);
5668 ASSERT(isolate->heap()->new_space()->Contains(new_string)); 5638 ASSERT(isolate->heap()->new_space()->Contains(new_string));
5669 5639
5670 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5671 Char* write_cursor = reinterpret_cast<Char*>( 5640 Char* write_cursor = reinterpret_cast<Char*>(
5672 new_string->address() + SeqAsciiString::kHeaderSize); 5641 new_string->address() + SeqString::kHeaderSize);
5673 if (comma) *(write_cursor++) = ','; 5642 if (comma) *(write_cursor++) = ',';
5674 write_cursor = WriteQuoteJsonString<Char, Char>(isolate, 5643 write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
5675 write_cursor, 5644 write_cursor,
5676 characters); 5645 characters);
5677 int final_length = static_cast<int>( 5646 int final_length = static_cast<int>(
5678 write_cursor - reinterpret_cast<Char*>( 5647 write_cursor - reinterpret_cast<Char*>(
5679 new_string->address() + SeqAsciiString::kHeaderSize)); 5648 new_string->address() + SeqString::kHeaderSize));
5680 isolate->heap()->new_space()-> 5649 isolate->heap()->new_space()->
5681 template ShrinkStringAtAllocationBoundary<StringType>( 5650 template ShrinkStringAtAllocationBoundary<StringType>(
5682 new_string, final_length); 5651 new_string, final_length);
5683 return new_string; 5652 return new_string;
5684 } 5653 }
5685 5654
5686 5655
5687 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) { 5656 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
5688 NoHandleAllocation ha; 5657 NoHandleAllocation ha;
5689 CONVERT_CHECKED(String, str, args[0]); 5658 CONVERT_CHECKED(String, str, args[0]);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5747 // Even if our string is small enough to fit in new space we still have to 5716 // Even if our string is small enough to fit in new space we still have to
5748 // handle it being allocated in old space as may happen in the third 5717 // handle it being allocated in old space as may happen in the third
5749 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in 5718 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5750 // CEntryStub::GenerateCore. 5719 // CEntryStub::GenerateCore.
5751 return isolate->heap()->undefined_value(); 5720 return isolate->heap()->undefined_value();
5752 } 5721 }
5753 AssertNoAllocation no_gc; 5722 AssertNoAllocation no_gc;
5754 StringType* new_string = StringType::cast(new_object); 5723 StringType* new_string = StringType::cast(new_object);
5755 ASSERT(isolate->heap()->new_space()->Contains(new_string)); 5724 ASSERT(isolate->heap()->new_space()->Contains(new_string));
5756 5725
5757 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5758 Char* write_cursor = reinterpret_cast<Char*>( 5726 Char* write_cursor = reinterpret_cast<Char*>(
5759 new_string->address() + SeqAsciiString::kHeaderSize); 5727 new_string->address() + SeqString::kHeaderSize);
5760 *(write_cursor++) = '['; 5728 *(write_cursor++) = '[';
5761 for (int i = 0; i < length; i++) { 5729 for (int i = 0; i < length; i++) {
5762 if (i != 0) *(write_cursor++) = ','; 5730 if (i != 0) *(write_cursor++) = ',';
5763 String* str = String::cast(array->get(i)); 5731 String* str = String::cast(array->get(i));
5764 String::FlatContent content = str->GetFlatContent(); 5732 String::FlatContent content = str->GetFlatContent();
5765 ASSERT(content.IsFlat()); 5733 ASSERT(content.IsFlat());
5766 if (content.IsTwoByte()) { 5734 if (content.IsTwoByte()) {
5767 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, 5735 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
5768 write_cursor, 5736 write_cursor,
5769 content.ToUC16Vector()); 5737 content.ToUC16Vector());
5770 } else { 5738 } else {
5771 write_cursor = WriteQuoteJsonString<Char, char>(isolate, 5739 write_cursor = WriteQuoteJsonString<Char, char>(isolate,
5772 write_cursor, 5740 write_cursor,
5773 content.ToAsciiVector()); 5741 content.ToAsciiVector());
5774 } 5742 }
5775 } 5743 }
5776 *(write_cursor++) = ']'; 5744 *(write_cursor++) = ']';
5777 5745
5778 int final_length = static_cast<int>( 5746 int final_length = static_cast<int>(
5779 write_cursor - reinterpret_cast<Char*>( 5747 write_cursor - reinterpret_cast<Char*>(
5780 new_string->address() + SeqAsciiString::kHeaderSize)); 5748 new_string->address() + SeqString::kHeaderSize));
5781 isolate->heap()->new_space()-> 5749 isolate->heap()->new_space()->
5782 template ShrinkStringAtAllocationBoundary<StringType>( 5750 template ShrinkStringAtAllocationBoundary<StringType>(
5783 new_string, final_length); 5751 new_string, final_length);
5784 return new_string; 5752 return new_string;
5785 } 5753 }
5786 5754
5787 5755
5788 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { 5756 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
5789 NoHandleAllocation ha; 5757 NoHandleAllocation ha;
5790 ASSERT(args.length() == 1); 5758 ASSERT(args.length() == 1);
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
6222 if (static_cast<uint32_t>(indices.length()) < limit) { 6190 if (static_cast<uint32_t>(indices.length()) < limit) {
6223 indices.Add(subject_length); 6191 indices.Add(subject_length);
6224 } 6192 }
6225 6193
6226 // The list indices now contains the end of each part to create. 6194 // The list indices now contains the end of each part to create.
6227 6195
6228 // Create JSArray of substrings separated by separator. 6196 // Create JSArray of substrings separated by separator.
6229 int part_count = indices.length(); 6197 int part_count = indices.length();
6230 6198
6231 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); 6199 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6200 MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements();
6201 if (maybe_result->IsFailure()) return maybe_result;
6232 result->set_length(Smi::FromInt(part_count)); 6202 result->set_length(Smi::FromInt(part_count));
6233 6203
6234 ASSERT(result->HasFastElements()); 6204 ASSERT(result->HasFastElements());
6235 6205
6236 if (part_count == 1 && indices.at(0) == subject_length) { 6206 if (part_count == 1 && indices.at(0) == subject_length) {
6237 FixedArray::cast(result->elements())->set(0, *subject); 6207 FixedArray::cast(result->elements())->set(0, *subject);
6238 return *result; 6208 return *result;
6239 } 6209 }
6240 6210
6241 Handle<FixedArray> elements(FixedArray::cast(result->elements())); 6211 Handle<FixedArray> elements(FixedArray::cast(result->elements()));
(...skipping 26 matching lines...) Expand all
6268 // not in the cache and fills the remainder with smi zeros. Returns 6238 // not in the cache and fills the remainder with smi zeros. Returns
6269 // the length of the successfully copied prefix. 6239 // the length of the successfully copied prefix.
6270 static int CopyCachedAsciiCharsToArray(Heap* heap, 6240 static int CopyCachedAsciiCharsToArray(Heap* heap,
6271 const char* chars, 6241 const char* chars,
6272 FixedArray* elements, 6242 FixedArray* elements,
6273 int length) { 6243 int length) {
6274 AssertNoAllocation no_gc; 6244 AssertNoAllocation no_gc;
6275 FixedArray* ascii_cache = heap->single_character_string_cache(); 6245 FixedArray* ascii_cache = heap->single_character_string_cache();
6276 Object* undefined = heap->undefined_value(); 6246 Object* undefined = heap->undefined_value();
6277 int i; 6247 int i;
6248 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6278 for (i = 0; i < length; ++i) { 6249 for (i = 0; i < length; ++i) {
6279 Object* value = ascii_cache->get(chars[i]); 6250 Object* value = ascii_cache->get(chars[i]);
6280 if (value == undefined) break; 6251 if (value == undefined) break;
6281 ASSERT(!heap->InNewSpace(value)); 6252 elements->set(i, value, mode);
6282 elements->set(i, value, SKIP_WRITE_BARRIER);
6283 } 6253 }
6284 if (i < length) { 6254 if (i < length) {
6285 ASSERT(Smi::FromInt(0) == 0); 6255 ASSERT(Smi::FromInt(0) == 0);
6286 memset(elements->data_start() + i, 0, kPointerSize * (length - i)); 6256 memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6287 } 6257 }
6288 #ifdef DEBUG 6258 #ifdef DEBUG
6289 for (int j = 0; j < length; ++j) { 6259 for (int j = 0; j < length; ++j) {
6290 Object* element = elements->get(j); 6260 Object* element = elements->get(j);
6291 ASSERT(element == Smi::FromInt(0) || 6261 ASSERT(element == Smi::FromInt(0) ||
6292 (element->IsString() && String::cast(element)->LooksValid())); 6262 (element->IsString() && String::cast(element)->LooksValid()));
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
6596 if (!args[1]->IsSmi()) { 6566 if (!args[1]->IsSmi()) {
6597 isolate->context()->mark_out_of_memory(); 6567 isolate->context()->mark_out_of_memory();
6598 return Failure::OutOfMemoryException(); 6568 return Failure::OutOfMemoryException();
6599 } 6569 }
6600 int array_length = args.smi_at(1); 6570 int array_length = args.smi_at(1);
6601 CONVERT_CHECKED(String, special, args[2]); 6571 CONVERT_CHECKED(String, special, args[2]);
6602 6572
6603 // This assumption is used by the slice encoding in one or two smis. 6573 // This assumption is used by the slice encoding in one or two smis.
6604 ASSERT(Smi::kMaxValue >= String::kMaxLength); 6574 ASSERT(Smi::kMaxValue >= String::kMaxLength);
6605 6575
6576 MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements();
6577 if (maybe_result->IsFailure()) return maybe_result;
6578
6606 int special_length = special->length(); 6579 int special_length = special->length();
6607 if (!array->HasFastElements()) { 6580 if (!array->HasFastElements()) {
6608 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6581 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6609 } 6582 }
6610 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6583 FixedArray* fixed_array = FixedArray::cast(array->elements());
6611 if (fixed_array->length() < array_length) { 6584 if (fixed_array->length() < array_length) {
6612 array_length = fixed_array->length(); 6585 array_length = fixed_array->length();
6613 } 6586 }
6614 6587
6615 if (array_length == 0) { 6588 if (array_length == 0) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
6823 } 6796 }
6824 } 6797 }
6825 ASSERT(cursor <= buffer.length()); 6798 ASSERT(cursor <= buffer.length());
6826 } 6799 }
6827 6800
6828 6801
6829 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { 6802 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
6830 NoHandleAllocation ha; 6803 NoHandleAllocation ha;
6831 ASSERT(args.length() == 3); 6804 ASSERT(args.length() == 3);
6832 CONVERT_CHECKED(JSArray, elements_array, args[0]); 6805 CONVERT_CHECKED(JSArray, elements_array, args[0]);
6833 RUNTIME_ASSERT(elements_array->HasFastElements()); 6806 RUNTIME_ASSERT(elements_array->HasFastElements() ||
6807 elements_array->HasFastSmiOnlyElements());
6834 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); 6808 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
6835 CONVERT_CHECKED(String, separator, args[2]); 6809 CONVERT_CHECKED(String, separator, args[2]);
6836 // elements_array is fast-mode JSarray of alternating positions 6810 // elements_array is fast-mode JSarray of alternating positions
6837 // (increasing order) and strings. 6811 // (increasing order) and strings.
6838 // array_length is length of original array (used to add separators); 6812 // array_length is length of original array (used to add separators);
6839 // separator is string to put between elements. Assumed to be non-empty. 6813 // separator is string to put between elements. Assumed to be non-empty.
6840 6814
6841 // Find total length of join result. 6815 // Find total length of join result.
6842 int string_length = 0; 6816 int string_length = 0;
6843 bool is_ascii = true; 6817 bool is_ascii = true;
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
7990 HandleScope scope(isolate); 7964 HandleScope scope(isolate);
7991 ASSERT(args.length() == 2); 7965 ASSERT(args.length() == 2);
7992 // First argument is a function to use as a constructor. 7966 // First argument is a function to use as a constructor.
7993 CONVERT_ARG_CHECKED(JSFunction, function, 0); 7967 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7994 7968
7995 // Second argument is either null or an array of bound arguments. 7969 // Second argument is either null or an array of bound arguments.
7996 Handle<FixedArray> bound_args; 7970 Handle<FixedArray> bound_args;
7997 int bound_argc = 0; 7971 int bound_argc = 0;
7998 if (!args[1]->IsNull()) { 7972 if (!args[1]->IsNull()) {
7999 CONVERT_ARG_CHECKED(JSArray, params, 1); 7973 CONVERT_ARG_CHECKED(JSArray, params, 1);
8000 RUNTIME_ASSERT(params->HasFastElements()); 7974 RUNTIME_ASSERT(params->HasFastTypeElements());
8001 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements())); 7975 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements()));
8002 bound_argc = Smi::cast(params->length())->value(); 7976 bound_argc = Smi::cast(params->length())->value();
8003 } 7977 }
8004 7978
8005 int total_argc = 0; 7979 int total_argc = 0;
8006 SmartArrayPointer<Object**> param_data = 7980 SmartArrayPointer<Object**> param_data =
8007 GetNonBoundArguments(bound_argc, &total_argc); 7981 GetNonBoundArguments(bound_argc, &total_argc);
8008 for (int i = 0; i < bound_argc; i++) { 7982 for (int i = 0; i < bound_argc; i++) {
8009 Handle<Object> val = Handle<Object>(bound_args->get(i)); 7983 Handle<Object> val = Handle<Object>(bound_args->get(i));
8010 param_data[i] = val.location(); 7984 param_data[i] = val.location();
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
8300 CONVERT_ARG_CHECKED(JSFunction, function, 0); 8274 CONVERT_ARG_CHECKED(JSFunction, function, 0);
8301 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 8275 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
8302 function->MarkForLazyRecompilation(); 8276 function->MarkForLazyRecompilation();
8303 return isolate->heap()->undefined_value(); 8277 return isolate->heap()->undefined_value();
8304 } 8278 }
8305 8279
8306 8280
8307 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) { 8281 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
8308 HandleScope scope(isolate); 8282 HandleScope scope(isolate);
8309 ASSERT(args.length() == 1); 8283 ASSERT(args.length() == 1);
8284 // The least significant bit (after untagging) indicates whether the
8285 // function is currently optimized, regardless of reason.
8310 if (!V8::UseCrankshaft()) { 8286 if (!V8::UseCrankshaft()) {
8311 return Smi::FromInt(4); // 4 == "never". 8287 return Smi::FromInt(4); // 4 == "never".
8312 } 8288 }
8313 if (FLAG_always_opt) { 8289 if (FLAG_always_opt) {
8314 return Smi::FromInt(3); // 3 == "always". 8290 return Smi::FromInt(3); // 3 == "always".
8315 } 8291 }
8316 CONVERT_ARG_CHECKED(JSFunction, function, 0); 8292 CONVERT_ARG_CHECKED(JSFunction, function, 0);
8317 return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". 8293 return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
8318 : Smi::FromInt(2); // 2 == "no". 8294 : Smi::FromInt(2); // 2 == "no".
8319 } 8295 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
8472 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); 8448 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8473 } 8449 }
8474 8450
8475 for (int i = 0; i < argc; ++i) { 8451 for (int i = 0; i < argc; ++i) {
8476 MaybeObject* maybe = arguments->GetElement(offset + i); 8452 MaybeObject* maybe = arguments->GetElement(offset + i);
8477 Object* object; 8453 Object* object;
8478 if (!maybe->To<Object>(&object)) return maybe; 8454 if (!maybe->To<Object>(&object)) return maybe;
8479 argv[i] = Handle<Object>(object); 8455 argv[i] = Handle<Object>(object);
8480 } 8456 }
8481 8457
8482 bool threw = false; 8458 bool threw;
8483 Handle<JSReceiver> hfun(fun); 8459 Handle<JSReceiver> hfun(fun);
8484 Handle<Object> hreceiver(receiver); 8460 Handle<Object> hreceiver(receiver);
8485 Handle<Object> result = Execution::Call( 8461 Handle<Object> result = Execution::Call(
8486 hfun, hreceiver, argc, reinterpret_cast<Object***>(argv), &threw, true); 8462 hfun, hreceiver, argc, reinterpret_cast<Object***>(argv), &threw, true);
8487 8463
8488 if (threw) return Failure::Exception(); 8464 if (threw) return Failure::Exception();
8489 return *result; 8465 return *result;
8490 } 8466 }
8491 8467
8492 8468
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
8639 if (holder.is_null()) { 8615 if (holder.is_null()) {
8640 return isolate->heap()->true_value(); 8616 return isolate->heap()->true_value();
8641 } 8617 }
8642 8618
8643 // If the slot was found in a context, it should be DONT_DELETE. 8619 // If the slot was found in a context, it should be DONT_DELETE.
8644 if (holder->IsContext()) { 8620 if (holder->IsContext()) {
8645 return isolate->heap()->false_value(); 8621 return isolate->heap()->false_value();
8646 } 8622 }
8647 8623
8648 // The slot was found in a JSObject, either a context extension object, 8624 // The slot was found in a JSObject, either a context extension object,
8649 // the global object, or an arguments object. Try to delete it 8625 // the global object, or the subject of a with. Try to delete it
8650 // (respecting DONT_DELETE). For consistency with V8's usual behavior, 8626 // (respecting DONT_DELETE).
8651 // which allows deleting all parameters in functions that mention
8652 // 'arguments', we do this even for the case of slots found on an
8653 // arguments object. The slot was found on an arguments object if the
8654 // index is non-negative.
8655 Handle<JSObject> object = Handle<JSObject>::cast(holder); 8627 Handle<JSObject> object = Handle<JSObject>::cast(holder);
8656 if (index >= 0) { 8628 return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
8657 return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
8658 } else {
8659 return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
8660 }
8661 } 8629 }
8662 8630
8663 8631
8664 // A mechanism to return a pair of Object pointers in registers (if possible). 8632 // A mechanism to return a pair of Object pointers in registers (if possible).
8665 // How this is achieved is calling convention-dependent. 8633 // How this is achieved is calling convention-dependent.
8666 // All currently supported x86 compiles uses calling conventions that are cdecl 8634 // All currently supported x86 compiles uses calling conventions that are cdecl
8667 // variants where a 64-bit value is returned in two 32-bit registers 8635 // variants where a 64-bit value is returned in two 32-bit registers
8668 // (edx:eax on ia32, r1:r0 on ARM). 8636 // (edx:eax on ia32, r1:r0 on ARM).
8669 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. 8637 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
8670 // In Win64 calling convention, a struct of two pointers is returned in memory, 8638 // In Win64 calling convention, a struct of two pointers is returned in memory,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
8735 int index; 8703 int index;
8736 PropertyAttributes attributes; 8704 PropertyAttributes attributes;
8737 ContextLookupFlags flags = FOLLOW_CHAINS; 8705 ContextLookupFlags flags = FOLLOW_CHAINS;
8738 BindingFlags binding_flags; 8706 BindingFlags binding_flags;
8739 Handle<Object> holder = context->Lookup(name, 8707 Handle<Object> holder = context->Lookup(name,
8740 flags, 8708 flags,
8741 &index, 8709 &index,
8742 &attributes, 8710 &attributes,
8743 &binding_flags); 8711 &binding_flags);
8744 8712
8745 // If the index is non-negative, the slot has been found in a local 8713 // If the index is non-negative, the slot has been found in a context.
8746 // variable or a parameter. Read it from the context object or the
8747 // arguments object.
8748 if (index >= 0) { 8714 if (index >= 0) {
8749 // If the "property" we were looking for is a local variable or an 8715 ASSERT(holder->IsContext());
8750 // argument in a context, the receiver is the global object; see 8716 // If the "property" we were looking for is a local variable, the
8751 // ECMA-262, 3rd., 10.1.6 and 10.2.3. 8717 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
8752 // 8718 //
8753 // Use the hole as the receiver to signal that the receiver is 8719 // Use the hole as the receiver to signal that the receiver is implicit
8754 // implicit and that the global receiver should be used. 8720 // and that the global receiver should be used (as distinguished from an
8721 // explicit receiver that happens to be a global object).
8755 Handle<Object> receiver = isolate->factory()->the_hole_value(); 8722 Handle<Object> receiver = isolate->factory()->the_hole_value();
8756 MaybeObject* value = (holder->IsContext()) 8723 Object* value = Context::cast(*holder)->get(index);
8757 ? Context::cast(*holder)->get(index)
8758 : JSObject::cast(*holder)->GetElement(index);
8759 // Check for uninitialized bindings. 8724 // Check for uninitialized bindings.
8760 if (holder->IsContext() && 8725 if (binding_flags == MUTABLE_CHECK_INITIALIZED && value->IsTheHole()) {
8761 binding_flags == MUTABLE_CHECK_INITIALIZED &&
8762 value->IsTheHole()) {
8763 Handle<Object> reference_error = 8726 Handle<Object> reference_error =
8764 isolate->factory()->NewReferenceError("not_defined", 8727 isolate->factory()->NewReferenceError("not_defined",
8765 HandleVector(&name, 1)); 8728 HandleVector(&name, 1));
8766 return MakePair(isolate->Throw(*reference_error), NULL); 8729 return MakePair(isolate->Throw(*reference_error), NULL);
8767 } else { 8730 } else {
8768 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); 8731 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8769 } 8732 }
8770 } 8733 }
8771 8734
8772 // If the holder is found, we read the property from it. 8735 // Otherwise, if the slot was found the holder is a context extension
8773 if (!holder.is_null() && holder->IsJSObject()) { 8736 // object, subject of a with, or a global object. We read the named
8774 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); 8737 // property from it.
8775 JSObject* object = JSObject::cast(*holder); 8738 if (!holder.is_null()) {
8776 Object* receiver; 8739 Handle<JSObject> object = Handle<JSObject>::cast(holder);
8777 if (object->IsGlobalObject()) { 8740 ASSERT(object->HasProperty(*name));
8778 receiver = GlobalObject::cast(object)->global_receiver(); 8741 // GetProperty below can cause GC.
8779 } else if (context->is_exception_holder(*holder)) { 8742 Handle<Object> receiver_handle(object->IsGlobalObject()
8780 // Use the hole as the receiver to signal that the receiver is 8743 ? GlobalObject::cast(*object)->global_receiver()
8781 // implicit and that the global receiver should be used. 8744 : ComputeReceiverForNonGlobal(isolate, *object));
8782 receiver = isolate->heap()->the_hole_value();
8783 } else {
8784 receiver = ComputeReceiverForNonGlobal(isolate, object);
8785 }
8786 8745
8787 // GetProperty below can cause GC. 8746 // No need to unhole the value here. This is taken care of by the
8788 Handle<Object> receiver_handle(receiver);
8789
8790 // No need to unhole the value here. This is taken care of by the
8791 // GetProperty function. 8747 // GetProperty function.
8792 MaybeObject* value = object->GetProperty(*name); 8748 MaybeObject* value = object->GetProperty(*name);
8793 return MakePair(value, *receiver_handle); 8749 return MakePair(value, *receiver_handle);
8794 } 8750 }
8795 8751
8796 if (throw_error) { 8752 if (throw_error) {
8797 // The property doesn't exist - throw exception. 8753 // The property doesn't exist - throw exception.
8798 Handle<Object> reference_error = 8754 Handle<Object> reference_error =
8799 isolate->factory()->NewReferenceError("not_defined", 8755 isolate->factory()->NewReferenceError("not_defined",
8800 HandleVector(&name, 1)); 8756 HandleVector(&name, 1));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8833 PropertyAttributes attributes; 8789 PropertyAttributes attributes;
8834 ContextLookupFlags flags = FOLLOW_CHAINS; 8790 ContextLookupFlags flags = FOLLOW_CHAINS;
8835 BindingFlags binding_flags; 8791 BindingFlags binding_flags;
8836 Handle<Object> holder = context->Lookup(name, 8792 Handle<Object> holder = context->Lookup(name,
8837 flags, 8793 flags,
8838 &index, 8794 &index,
8839 &attributes, 8795 &attributes,
8840 &binding_flags); 8796 &binding_flags);
8841 8797
8842 if (index >= 0) { 8798 if (index >= 0) {
8843 if (holder->IsContext()) { 8799 // The property was found in a context slot.
8844 Handle<Context> context = Handle<Context>::cast(holder); 8800 Handle<Context> context = Handle<Context>::cast(holder);
8845 if (binding_flags == MUTABLE_CHECK_INITIALIZED && 8801 if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
8846 context->get(index)->IsTheHole()) { 8802 context->get(index)->IsTheHole()) {
8847 Handle<Object> error = 8803 Handle<Object> error =
8848 isolate->factory()->NewReferenceError("not_defined", 8804 isolate->factory()->NewReferenceError("not_defined",
8849 HandleVector(&name, 1)); 8805 HandleVector(&name, 1));
8850 return isolate->Throw(*error); 8806 return isolate->Throw(*error);
8851 } 8807 }
8852 // Ignore if read_only variable. 8808 // Ignore if read_only variable.
8853 if ((attributes & READ_ONLY) == 0) { 8809 if ((attributes & READ_ONLY) == 0) {
8854 // Context is a fixed array and set cannot fail. 8810 // Context is a fixed array and set cannot fail.
8855 context->set(index, *value); 8811 context->set(index, *value);
8856 } else if (strict_mode == kStrictMode) { 8812 } else if (strict_mode == kStrictMode) {
8857 // Setting read only property in strict mode. 8813 // Setting read only property in strict mode.
8858 Handle<Object> error = 8814 Handle<Object> error =
8859 isolate->factory()->NewTypeError("strict_cannot_assign", 8815 isolate->factory()->NewTypeError("strict_cannot_assign",
8860 HandleVector(&name, 1)); 8816 HandleVector(&name, 1));
8861 return isolate->Throw(*error); 8817 return isolate->Throw(*error);
8862 }
8863 } else {
8864 ASSERT((attributes & READ_ONLY) == 0);
8865 Handle<Object> result =
8866 SetElement(Handle<JSObject>::cast(holder), index, value, strict_mode);
8867 if (result.is_null()) {
8868 ASSERT(isolate->has_pending_exception());
8869 return Failure::Exception();
8870 }
8871 } 8818 }
8872 return *value; 8819 return *value;
8873 } 8820 }
8874 8821
8875 // Slow case: The property is not in a FixedArray context. 8822 // Slow case: The property is not in a context slot. It is either in a
8876 // It is either in an JSObject extension context or it was not found. 8823 // context extension object, a property of the subject of a with, or a
8877 Handle<JSObject> context_ext; 8824 // property of the global object.
8825 Handle<JSObject> object;
8878 8826
8879 if (!holder.is_null()) { 8827 if (!holder.is_null()) {
8880 // The property exists in the extension context. 8828 // The property exists on the holder.
8881 context_ext = Handle<JSObject>::cast(holder); 8829 object = Handle<JSObject>::cast(holder);
8882 } else { 8830 } else {
8883 // The property was not found. 8831 // The property was not found.
8884 ASSERT(attributes == ABSENT); 8832 ASSERT(attributes == ABSENT);
8885 8833
8886 if (strict_mode == kStrictMode) { 8834 if (strict_mode == kStrictMode) {
8887 // Throw in strict mode (assignment to undefined variable). 8835 // Throw in strict mode (assignment to undefined variable).
8888 Handle<Object> error = 8836 Handle<Object> error =
8889 isolate->factory()->NewReferenceError( 8837 isolate->factory()->NewReferenceError(
8890 "not_defined", HandleVector(&name, 1)); 8838 "not_defined", HandleVector(&name, 1));
8891 return isolate->Throw(*error); 8839 return isolate->Throw(*error);
8892 } 8840 }
8893 // In non-strict mode, the property is stored in the global context. 8841 // In non-strict mode, the property is added to the global object.
8894 attributes = NONE; 8842 attributes = NONE;
8895 context_ext = Handle<JSObject>(isolate->context()->global()); 8843 object = Handle<JSObject>(isolate->context()->global());
8896 } 8844 }
8897 8845
8898 // Set the property, but ignore if read_only variable on the context 8846 // Set the property if it's not read only or doesn't yet exist.
8899 // extension object itself.
8900 if ((attributes & READ_ONLY) == 0 || 8847 if ((attributes & READ_ONLY) == 0 ||
8901 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { 8848 (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
8902 RETURN_IF_EMPTY_HANDLE( 8849 RETURN_IF_EMPTY_HANDLE(
8903 isolate, 8850 isolate,
8904 SetProperty(context_ext, name, value, NONE, strict_mode)); 8851 SetProperty(object, name, value, NONE, strict_mode));
8905 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { 8852 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
8906 // Setting read only property in strict mode. 8853 // Setting read only property in strict mode.
8907 Handle<Object> error = 8854 Handle<Object> error =
8908 isolate->factory()->NewTypeError( 8855 isolate->factory()->NewTypeError(
8909 "strict_cannot_assign", HandleVector(&name, 1)); 8856 "strict_cannot_assign", HandleVector(&name, 1));
8910 return isolate->Throw(*error); 8857 return isolate->Throw(*error);
8911 } 8858 }
8912 return *value; 8859 return *value;
8913 } 8860 }
8914 8861
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
9114 9061
9115 9062
9116 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { 9063 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
9117 HandleScope scope(isolate); 9064 HandleScope scope(isolate);
9118 ASSERT(args.length() == 2); 9065 ASSERT(args.length() == 2);
9119 9066
9120 CONVERT_ARG_CHECKED(String, str, 0); 9067 CONVERT_ARG_CHECKED(String, str, 0);
9121 FlattenString(str); 9068 FlattenString(str);
9122 9069
9123 CONVERT_ARG_CHECKED(JSArray, output, 1); 9070 CONVERT_ARG_CHECKED(JSArray, output, 1);
9071
9072 MaybeObject* maybe_result_array =
9073 output->EnsureCanContainNonSmiElements();
9074 if (maybe_result_array->IsFailure()) return maybe_result_array;
9124 RUNTIME_ASSERT(output->HasFastElements()); 9075 RUNTIME_ASSERT(output->HasFastElements());
9125 9076
9126 AssertNoAllocation no_allocation; 9077 AssertNoAllocation no_allocation;
9127 9078
9128 FixedArray* output_array = FixedArray::cast(output->elements()); 9079 FixedArray* output_array = FixedArray::cast(output->elements());
9129 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); 9080 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9130 bool result; 9081 bool result;
9131 String::FlatContent str_content = str->GetFlatContent(); 9082 String::FlatContent str_content = str->GetFlatContent();
9132 if (str_content.IsAscii()) { 9083 if (str_content.IsAscii()) {
9133 result = DateParser::Parse(str_content.ToAsciiVector(), 9084 result = DateParser::Parse(str_content.ToAsciiVector(),
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
9299 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 9250 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
9300 ASSERT(Context::cast(frame->context()) == *context); 9251 ASSERT(Context::cast(frame->context()) == *context);
9301 #endif 9252 #endif
9302 9253
9303 // Find where the 'eval' symbol is bound. It is unaliased only if 9254 // Find where the 'eval' symbol is bound. It is unaliased only if
9304 // it is bound in the global context. 9255 // it is bound in the global context.
9305 int index = -1; 9256 int index = -1;
9306 PropertyAttributes attributes = ABSENT; 9257 PropertyAttributes attributes = ABSENT;
9307 BindingFlags binding_flags; 9258 BindingFlags binding_flags;
9308 while (true) { 9259 while (true) {
9260 // Don't follow context chains in Context::Lookup and implement the loop
9261 // up the context chain here, so that we can know the context where eval
9262 // was found.
9309 receiver = context->Lookup(isolate->factory()->eval_symbol(), 9263 receiver = context->Lookup(isolate->factory()->eval_symbol(),
9310 FOLLOW_PROTOTYPE_CHAIN, 9264 FOLLOW_PROTOTYPE_CHAIN,
9311 &index, 9265 &index,
9312 &attributes, 9266 &attributes,
9313 &binding_flags); 9267 &binding_flags);
9314 // Stop search when eval is found or when the global context is 9268 // Stop search when eval is found or when the global context is
9315 // reached. 9269 // reached.
9316 if (attributes != ABSENT || context->IsGlobalContext()) break; 9270 if (attributes != ABSENT || context->IsGlobalContext()) break;
9317 context = Handle<Context>(context->previous(), isolate); 9271 context = Handle<Context>(context->previous(), isolate);
9318 } 9272 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
9414 } 9368 }
9415 9369
9416 9370
9417 // Push an object unto an array of objects if it is not already in the 9371 // Push an object unto an array of objects if it is not already in the
9418 // array. Returns true if the element was pushed on the stack and 9372 // array. Returns true if the element was pushed on the stack and
9419 // false otherwise. 9373 // false otherwise.
9420 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { 9374 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
9421 ASSERT(args.length() == 2); 9375 ASSERT(args.length() == 2);
9422 CONVERT_CHECKED(JSArray, array, args[0]); 9376 CONVERT_CHECKED(JSArray, array, args[0]);
9423 CONVERT_CHECKED(JSObject, element, args[1]); 9377 CONVERT_CHECKED(JSObject, element, args[1]);
9424 RUNTIME_ASSERT(array->HasFastElements()); 9378 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
9425 int length = Smi::cast(array->length())->value(); 9379 int length = Smi::cast(array->length())->value();
9426 FixedArray* elements = FixedArray::cast(array->elements()); 9380 FixedArray* elements = FixedArray::cast(array->elements());
9427 for (int i = 0; i < length; i++) { 9381 for (int i = 0; i < length; i++) {
9428 if (elements->get(i) == element) return isolate->heap()->false_value(); 9382 if (elements->get(i) == element) return isolate->heap()->false_value();
9429 } 9383 }
9430 Object* obj; 9384 Object* obj;
9431 // Strict not needed. Used for cycle detection in Array join implementation. 9385 // Strict not needed. Used for cycle detection in Array join implementation.
9432 { MaybeObject* maybe_obj = 9386 { MaybeObject* maybe_obj =
9433 array->SetFastElement(length, element, kNonStrictMode, true); 9387 array->SetFastElement(length, element, kNonStrictMode, true);
9434 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9388 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
9497 index_offset_ += delta; 9451 index_offset_ += delta;
9498 } 9452 }
9499 } 9453 }
9500 9454
9501 Handle<JSArray> ToArray() { 9455 Handle<JSArray> ToArray() {
9502 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); 9456 Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
9503 Handle<Object> length = 9457 Handle<Object> length =
9504 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); 9458 isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
9505 Handle<Map> map; 9459 Handle<Map> map;
9506 if (fast_elements_) { 9460 if (fast_elements_) {
9507 map = isolate_->factory()->GetFastElementsMap(Handle<Map>(array->map())); 9461 map = isolate_->factory()->GetElementsTransitionMap(array,
9462 FAST_ELEMENTS);
9508 } else { 9463 } else {
9509 map = isolate_->factory()->GetSlowElementsMap(Handle<Map>(array->map())); 9464 map = isolate_->factory()->GetElementsTransitionMap(array,
9465 DICTIONARY_ELEMENTS);
9510 } 9466 }
9511 array->set_map(*map); 9467 array->set_map(*map);
9512 array->set_length(*length); 9468 array->set_length(*length);
9513 array->set_elements(*storage_); 9469 array->set_elements(*storage_);
9514 return array; 9470 return array;
9515 } 9471 }
9516 9472
9517 private: 9473 private:
9518 // Convert storage to dictionary mode. 9474 // Convert storage to dictionary mode.
9519 void SetDictionaryMode(uint32_t index) { 9475 void SetDictionaryMode(uint32_t index) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
9643 uint32_t b = *bp; 9599 uint32_t b = *bp;
9644 return (a == b) ? 0 : (a < b) ? -1 : 1; 9600 return (a == b) ? 0 : (a < b) ? -1 : 1;
9645 } 9601 }
9646 9602
9647 9603
9648 static void CollectElementIndices(Handle<JSObject> object, 9604 static void CollectElementIndices(Handle<JSObject> object,
9649 uint32_t range, 9605 uint32_t range,
9650 List<uint32_t>* indices) { 9606 List<uint32_t>* indices) {
9651 ElementsKind kind = object->GetElementsKind(); 9607 ElementsKind kind = object->GetElementsKind();
9652 switch (kind) { 9608 switch (kind) {
9609 case FAST_SMI_ONLY_ELEMENTS:
9653 case FAST_ELEMENTS: { 9610 case FAST_ELEMENTS: {
9654 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 9611 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
9655 uint32_t length = static_cast<uint32_t>(elements->length()); 9612 uint32_t length = static_cast<uint32_t>(elements->length());
9656 if (range < length) length = range; 9613 if (range < length) length = range;
9657 for (uint32_t i = 0; i < length; i++) { 9614 for (uint32_t i = 0; i < length; i++) {
9658 if (!elements->get(i)->IsTheHole()) { 9615 if (!elements->get(i)->IsTheHole()) {
9659 indices->Add(i); 9616 indices->Add(i);
9660 } 9617 }
9661 } 9618 }
9662 break; 9619 break;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
9762 * with the element index and the element's value. 9719 * with the element index and the element's value.
9763 * Afterwards it increments the base-index of the visitor by the array 9720 * Afterwards it increments the base-index of the visitor by the array
9764 * length. 9721 * length.
9765 * Returns false if any access threw an exception, otherwise true. 9722 * Returns false if any access threw an exception, otherwise true.
9766 */ 9723 */
9767 static bool IterateElements(Isolate* isolate, 9724 static bool IterateElements(Isolate* isolate,
9768 Handle<JSArray> receiver, 9725 Handle<JSArray> receiver,
9769 ArrayConcatVisitor* visitor) { 9726 ArrayConcatVisitor* visitor) {
9770 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); 9727 uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
9771 switch (receiver->GetElementsKind()) { 9728 switch (receiver->GetElementsKind()) {
9729 case FAST_SMI_ONLY_ELEMENTS:
9772 case FAST_ELEMENTS: { 9730 case FAST_ELEMENTS: {
9773 // Run through the elements FixedArray and use HasElement and GetElement 9731 // Run through the elements FixedArray and use HasElement and GetElement
9774 // to check the prototype for missing elements. 9732 // to check the prototype for missing elements.
9775 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 9733 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
9776 int fast_length = static_cast<int>(length); 9734 int fast_length = static_cast<int>(length);
9777 ASSERT(fast_length <= elements->length()); 9735 ASSERT(fast_length <= elements->length());
9778 for (int j = 0; j < fast_length; j++) { 9736 for (int j = 0; j < fast_length; j++) {
9779 HandleScope loop_scope(isolate); 9737 HandleScope loop_scope(isolate);
9780 Handle<Object> element_value(elements->get(j), isolate); 9738 Handle<Object> element_value(elements->get(j), isolate);
9781 if (!element_value->IsTheHole()) { 9739 if (!element_value->IsTheHole()) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
9990 } 9948 }
9991 9949
9992 9950
9993 // Move contents of argument 0 (an array) to argument 1 (an array) 9951 // Move contents of argument 0 (an array) to argument 1 (an array)
9994 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { 9952 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
9995 ASSERT(args.length() == 2); 9953 ASSERT(args.length() == 2);
9996 CONVERT_CHECKED(JSArray, from, args[0]); 9954 CONVERT_CHECKED(JSArray, from, args[0]);
9997 CONVERT_CHECKED(JSArray, to, args[1]); 9955 CONVERT_CHECKED(JSArray, to, args[1]);
9998 FixedArrayBase* new_elements = from->elements(); 9956 FixedArrayBase* new_elements = from->elements();
9999 MaybeObject* maybe_new_map; 9957 MaybeObject* maybe_new_map;
9958 ElementsKind elements_kind;
10000 if (new_elements->map() == isolate->heap()->fixed_array_map() || 9959 if (new_elements->map() == isolate->heap()->fixed_array_map() ||
10001 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { 9960 new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
10002 maybe_new_map = to->map()->GetFastElementsMap(); 9961 elements_kind = FAST_ELEMENTS;
10003 } else if (new_elements->map() == 9962 } else if (new_elements->map() ==
10004 isolate->heap()->fixed_double_array_map()) { 9963 isolate->heap()->fixed_double_array_map()) {
10005 maybe_new_map = to->map()->GetFastDoubleElementsMap(); 9964 elements_kind = FAST_DOUBLE_ELEMENTS;
10006 } else { 9965 } else {
10007 maybe_new_map = to->map()->GetSlowElementsMap(); 9966 elements_kind = DICTIONARY_ELEMENTS;
10008 } 9967 }
9968 maybe_new_map = to->GetElementsTransitionMap(elements_kind);
10009 Object* new_map; 9969 Object* new_map;
10010 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 9970 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
10011 to->set_map(Map::cast(new_map)); 9971 to->set_map(Map::cast(new_map));
10012 to->set_elements(new_elements); 9972 to->set_elements(new_elements);
10013 to->set_length(from->length()); 9973 to->set_length(from->length());
10014 Object* obj; 9974 Object* obj;
10015 { MaybeObject* maybe_obj = from->ResetElements(); 9975 { MaybeObject* maybe_obj = from->ResetElements();
10016 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9976 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10017 } 9977 }
10018 from->set_length(Smi::FromInt(0)); 9978 from->set_length(Smi::FromInt(0));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
10083 for (int i = 0; i < keys_length; i++) { 10043 for (int i = 0; i < keys_length; i++) {
10084 Object* key = keys->get(i); 10044 Object* key = keys->get(i);
10085 uint32_t index = 0; 10045 uint32_t index = 0;
10086 if (!key->ToArrayIndex(&index) || index >= length) { 10046 if (!key->ToArrayIndex(&index) || index >= length) {
10087 // Zap invalid keys. 10047 // Zap invalid keys.
10088 keys->set_undefined(i); 10048 keys->set_undefined(i);
10089 } 10049 }
10090 } 10050 }
10091 return *isolate->factory()->NewJSArrayWithElements(keys); 10051 return *isolate->factory()->NewJSArrayWithElements(keys);
10092 } else { 10052 } else {
10093 ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); 10053 ASSERT(array->HasFastElements() ||
10054 array->HasFastSmiOnlyElements() ||
10055 array->HasFastDoubleElements());
10094 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); 10056 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
10095 // -1 means start of array. 10057 // -1 means start of array.
10096 single_interval->set(0, Smi::FromInt(-1)); 10058 single_interval->set(0, Smi::FromInt(-1));
10097 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); 10059 FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
10098 uint32_t actual_length = 10060 uint32_t actual_length =
10099 static_cast<uint32_t>(elements->length()); 10061 static_cast<uint32_t>(elements->length());
10100 uint32_t min_length = actual_length < length ? actual_length : length; 10062 uint32_t min_length = actual_length < length ? actual_length : length;
10101 Handle<Object> length_object = 10063 Handle<Object> length_object =
10102 isolate->factory()->NewNumber(static_cast<double>(min_length)); 10064 isolate->factory()->NewNumber(static_cast<double>(min_length));
10103 single_interval->set(1, *length_object); 10065 single_interval->set(1, *length_object);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
10202 result->holder())->FastPropertyAt(result->GetFieldIndex()); 10164 result->holder())->FastPropertyAt(result->GetFieldIndex());
10203 if (value->IsTheHole()) { 10165 if (value->IsTheHole()) {
10204 return heap->undefined_value(); 10166 return heap->undefined_value();
10205 } 10167 }
10206 return value; 10168 return value;
10207 case CONSTANT_FUNCTION: 10169 case CONSTANT_FUNCTION:
10208 return result->GetConstantFunction(); 10170 return result->GetConstantFunction();
10209 case CALLBACKS: { 10171 case CALLBACKS: {
10210 Object* structure = result->GetCallbackObject(); 10172 Object* structure = result->GetCallbackObject();
10211 if (structure->IsForeign() || structure->IsAccessorInfo()) { 10173 if (structure->IsForeign() || structure->IsAccessorInfo()) {
10212 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( 10174 MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
10213 receiver, structure, name, result->holder()); 10175 receiver, structure, name);
10214 if (!maybe_value->ToObject(&value)) { 10176 if (!maybe_value->ToObject(&value)) {
10215 if (maybe_value->IsRetryAfterGC()) return maybe_value; 10177 if (maybe_value->IsRetryAfterGC()) return maybe_value;
10216 ASSERT(maybe_value->IsException()); 10178 ASSERT(maybe_value->IsException());
10217 maybe_value = heap->isolate()->pending_exception(); 10179 maybe_value = heap->isolate()->pending_exception();
10218 heap->isolate()->clear_pending_exception(); 10180 heap->isolate()->clear_pending_exception();
10219 if (caught_exception != NULL) { 10181 if (caught_exception != NULL) {
10220 *caught_exception = true; 10182 *caught_exception = true;
10221 } 10183 }
10222 return maybe_value; 10184 return maybe_value;
10223 } 10185 }
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
11453 // NOTE: This might require several heap iterations. If the SharedFunctionInfo 11415 // NOTE: This might require several heap iterations. If the SharedFunctionInfo
11454 // which is found is not compiled it is compiled and the heap is iterated 11416 // which is found is not compiled it is compiled and the heap is iterated
11455 // again as the compilation might create inner functions from the newly 11417 // again as the compilation might create inner functions from the newly
11456 // compiled function and the actual requested break point might be in one of 11418 // compiled function and the actual requested break point might be in one of
11457 // these functions. 11419 // these functions.
11458 bool done = false; 11420 bool done = false;
11459 // The current candidate for the source position: 11421 // The current candidate for the source position:
11460 int target_start_position = RelocInfo::kNoPosition; 11422 int target_start_position = RelocInfo::kNoPosition;
11461 Handle<SharedFunctionInfo> target; 11423 Handle<SharedFunctionInfo> target;
11462 while (!done) { 11424 while (!done) {
11463 HeapIterator iterator; 11425 { // Extra scope for iterator and no-allocation.
11464 for (HeapObject* obj = iterator.next(); 11426 isolate->heap()->EnsureHeapIsIterable();
11465 obj != NULL; obj = iterator.next()) { 11427 AssertNoAllocation no_alloc_during_heap_iteration;
11466 if (obj->IsSharedFunctionInfo()) { 11428 HeapIterator iterator;
11467 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); 11429 for (HeapObject* obj = iterator.next();
11468 if (shared->script() == *script) { 11430 obj != NULL; obj = iterator.next()) {
11469 // If the SharedFunctionInfo found has the requested script data and 11431 if (obj->IsSharedFunctionInfo()) {
11470 // contains the source position it is a candidate. 11432 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
11471 int start_position = shared->function_token_position(); 11433 if (shared->script() == *script) {
11472 if (start_position == RelocInfo::kNoPosition) { 11434 // If the SharedFunctionInfo found has the requested script data and
11473 start_position = shared->start_position(); 11435 // contains the source position it is a candidate.
11474 } 11436 int start_position = shared->function_token_position();
11475 if (start_position <= position && 11437 if (start_position == RelocInfo::kNoPosition) {
11476 position <= shared->end_position()) { 11438 start_position = shared->start_position();
11477 // If there is no candidate or this function is within the current 11439 }
11478 // candidate this is the new candidate. 11440 if (start_position <= position &&
11479 if (target.is_null()) { 11441 position <= shared->end_position()) {
11480 target_start_position = start_position; 11442 // If there is no candidate or this function is within the current
11481 target = shared; 11443 // candidate this is the new candidate.
11482 } else { 11444 if (target.is_null()) {
11483 if (target_start_position == start_position && 11445 target_start_position = start_position;
11484 shared->end_position() == target->end_position()) { 11446 target = shared;
11485 // If a top-level function contain only one function 11447 } else {
11486 // declartion the source for the top-level and the function is 11448 if (target_start_position == start_position &&
11487 // the same. In that case prefer the non top-level function. 11449 shared->end_position() == target->end_position()) {
11488 if (!shared->is_toplevel()) { 11450 // If a top-level function contain only one function
11451 // declartion the source for the top-level and the
11452 // function is the same. In that case prefer the non
11453 // top-level function.
11454 if (!shared->is_toplevel()) {
11455 target_start_position = start_position;
11456 target = shared;
11457 }
11458 } else if (target_start_position <= start_position &&
11459 shared->end_position() <= target->end_position()) {
11460 // This containment check includes equality as a function
11461 // inside a top-level function can share either start or end
11462 // position with the top-level function.
11489 target_start_position = start_position; 11463 target_start_position = start_position;
11490 target = shared; 11464 target = shared;
11491 } 11465 }
11492 } else if (target_start_position <= start_position &&
11493 shared->end_position() <= target->end_position()) {
11494 // This containment check includes equality as a function inside
11495 // a top-level function can share either start or end position
11496 // with the top-level function.
11497 target_start_position = start_position;
11498 target = shared;
11499 } 11466 }
11500 } 11467 }
11501 } 11468 }
11502 } 11469 }
11503 } 11470 } // End for loop.
11504 } 11471 } // End No allocation scope.
11505 11472
11506 if (target.is_null()) { 11473 if (target.is_null()) {
11507 return isolate->heap()->undefined_value(); 11474 return isolate->heap()->undefined_value();
11508 } 11475 }
11509 11476
11510 // If the candidate found is compiled we are done. NOTE: when lazy 11477 // If the candidate found is compiled we are done. NOTE: when lazy
11511 // compilation of inner functions is introduced some additional checking 11478 // compilation of inner functions is introduced some additional checking
11512 // needs to be done here to compile inner functions. 11479 // needs to be done here to compile inner functions.
11513 done = target->is_compiled(); 11480 done = target->is_compiled();
11514 if (!done) { 11481 if (!done) {
11515 // If the candidate is not compiled compile it to reveal any inner 11482 // If the candidate is not compiled compile it to reveal any inner
11516 // functions which might contain the requested source position. 11483 // functions which might contain the requested source position.
11517 CompileLazyShared(target, KEEP_EXCEPTION); 11484 CompileLazyShared(target, KEEP_EXCEPTION);
11518 } 11485 }
11519 } 11486 } // End while loop.
11520 11487
11521 return *target; 11488 return *target;
11522 } 11489 }
11523 11490
11524 11491
11525 // Changes the state of a break point in a script and returns source position 11492 // Changes the state of a break point in a script and returns source position
11526 // where break point was set. NOTE: Regarding performance see the NOTE for 11493 // where break point was set. NOTE: Regarding performance see the NOTE for
11527 // GetScriptFromScriptData. 11494 // GetScriptFromScriptData.
11528 // args[0]: script to set break point in 11495 // args[0]: script to set break point in
11529 // args[1]: number: break source position (within the script source) 11496 // args[1]: number: break source position (within the script source)
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
11959 Handle<JSFunction>( 11926 Handle<JSFunction>(
11960 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, 11927 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
11961 context)); 11928 context));
11962 11929
11963 // Invoke the result of the compilation to get the evaluation function. 11930 // Invoke the result of the compilation to get the evaluation function.
11964 bool has_pending_exception; 11931 bool has_pending_exception;
11965 Handle<Object> receiver = isolate->global(); 11932 Handle<Object> receiver = isolate->global();
11966 Handle<Object> result = 11933 Handle<Object> result =
11967 Execution::Call(compiled_function, receiver, 0, NULL, 11934 Execution::Call(compiled_function, receiver, 0, NULL,
11968 &has_pending_exception); 11935 &has_pending_exception);
11936 // Clear the oneshot breakpoints so that the debugger does not step further.
11937 isolate->debug()->ClearStepping();
11969 if (has_pending_exception) return Failure::Exception(); 11938 if (has_pending_exception) return Failure::Exception();
11970 return *result; 11939 return *result;
11971 } 11940 }
11972 11941
11973 11942
11974 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) { 11943 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
11975 HandleScope scope(isolate); 11944 HandleScope scope(isolate);
11976 ASSERT(args.length() == 0); 11945 ASSERT(args.length() == 0);
11977 11946
11978 // Fill the script objects. 11947 // Fill the script objects.
11979 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts(); 11948 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
11980 11949
11981 // Convert the script objects to proper JS objects. 11950 // Convert the script objects to proper JS objects.
11982 for (int i = 0; i < instances->length(); i++) { 11951 for (int i = 0; i < instances->length(); i++) {
11983 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); 11952 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
11984 // Get the script wrapper in a local handle before calling GetScriptWrapper, 11953 // Get the script wrapper in a local handle before calling GetScriptWrapper,
11985 // because using 11954 // because using
11986 // instances->set(i, *GetScriptWrapper(script)) 11955 // instances->set(i, *GetScriptWrapper(script))
11987 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might 11956 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
11988 // already have deferenced the instances handle. 11957 // already have deferenced the instances handle.
11989 Handle<JSValue> wrapper = GetScriptWrapper(script); 11958 Handle<JSValue> wrapper = GetScriptWrapper(script);
11990 instances->set(i, *wrapper); 11959 instances->set(i, *wrapper);
11991 } 11960 }
11992 11961
11993 // Return result as a JS array. 11962 // Return result as a JS array.
11994 Handle<JSObject> result = 11963 Handle<JSObject> result =
11995 isolate->factory()->NewJSObject(isolate->array_function()); 11964 isolate->factory()->NewJSObject(isolate->array_function());
11996 Handle<JSArray>::cast(result)->SetContent(*instances); 11965 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
11997 return *result; 11966 return *result;
11998 } 11967 }
11999 11968
12000 11969
12001 // Helper function used by Runtime_DebugReferencedBy below. 11970 // Helper function used by Runtime_DebugReferencedBy below.
12002 static int DebugReferencedBy(JSObject* target, 11971 static int DebugReferencedBy(HeapIterator* iterator,
11972 JSObject* target,
12003 Object* instance_filter, int max_references, 11973 Object* instance_filter, int max_references,
12004 FixedArray* instances, int instances_size, 11974 FixedArray* instances, int instances_size,
12005 JSFunction* arguments_function) { 11975 JSFunction* arguments_function) {
12006 NoHandleAllocation ha; 11976 NoHandleAllocation ha;
12007 AssertNoAllocation no_alloc; 11977 AssertNoAllocation no_alloc;
12008 11978
12009 // Iterate the heap. 11979 // Iterate the heap.
12010 int count = 0; 11980 int count = 0;
12011 JSObject* last = NULL; 11981 JSObject* last = NULL;
12012 HeapIterator iterator;
12013 HeapObject* heap_obj = NULL; 11982 HeapObject* heap_obj = NULL;
12014 while (((heap_obj = iterator.next()) != NULL) && 11983 while (((heap_obj = iterator->next()) != NULL) &&
12015 (max_references == 0 || count < max_references)) { 11984 (max_references == 0 || count < max_references)) {
12016 // Only look at all JSObjects. 11985 // Only look at all JSObjects.
12017 if (heap_obj->IsJSObject()) { 11986 if (heap_obj->IsJSObject()) {
12018 // Skip context extension objects and argument arrays as these are 11987 // Skip context extension objects and argument arrays as these are
12019 // checked in the context of functions using them. 11988 // checked in the context of functions using them.
12020 JSObject* obj = JSObject::cast(heap_obj); 11989 JSObject* obj = JSObject::cast(heap_obj);
12021 if (obj->IsJSContextExtensionObject() || 11990 if (obj->IsJSContextExtensionObject() ||
12022 obj->map()->constructor() == arguments_function) { 11991 obj->map()->constructor() == arguments_function) {
12023 continue; 11992 continue;
12024 } 11993 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
12069 12038
12070 12039
12071 // Scan the heap for objects with direct references to an object 12040 // Scan the heap for objects with direct references to an object
12072 // args[0]: the object to find references to 12041 // args[0]: the object to find references to
12073 // args[1]: constructor function for instances to exclude (Mirror) 12042 // args[1]: constructor function for instances to exclude (Mirror)
12074 // args[2]: the the maximum number of objects to return 12043 // args[2]: the the maximum number of objects to return
12075 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { 12044 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
12076 ASSERT(args.length() == 3); 12045 ASSERT(args.length() == 3);
12077 12046
12078 // First perform a full GC in order to avoid references from dead objects. 12047 // First perform a full GC in order to avoid references from dead objects.
12079 isolate->heap()->CollectAllGarbage(false); 12048 isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
12049 // The heap iterator reserves the right to do a GC to make the heap iterable.
12050 // Due to the GC above we know it won't need to do that, but it seems cleaner
12051 // to get the heap iterator constructed before we start having unprotected
12052 // Object* locals that are not protected by handles.
12080 12053
12081 // Check parameters. 12054 // Check parameters.
12082 CONVERT_CHECKED(JSObject, target, args[0]); 12055 CONVERT_CHECKED(JSObject, target, args[0]);
12083 Object* instance_filter = args[1]; 12056 Object* instance_filter = args[1];
12084 RUNTIME_ASSERT(instance_filter->IsUndefined() || 12057 RUNTIME_ASSERT(instance_filter->IsUndefined() ||
12085 instance_filter->IsJSObject()); 12058 instance_filter->IsJSObject());
12086 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); 12059 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
12087 RUNTIME_ASSERT(max_references >= 0); 12060 RUNTIME_ASSERT(max_references >= 0);
12088 12061
12062
12089 // Get the constructor function for context extension and arguments array. 12063 // Get the constructor function for context extension and arguments array.
12090 JSObject* arguments_boilerplate = 12064 JSObject* arguments_boilerplate =
12091 isolate->context()->global_context()->arguments_boilerplate(); 12065 isolate->context()->global_context()->arguments_boilerplate();
12092 JSFunction* arguments_function = 12066 JSFunction* arguments_function =
12093 JSFunction::cast(arguments_boilerplate->map()->constructor()); 12067 JSFunction::cast(arguments_boilerplate->map()->constructor());
12094 12068
12095 // Get the number of referencing objects. 12069 // Get the number of referencing objects.
12096 int count; 12070 int count;
12097 count = DebugReferencedBy(target, instance_filter, max_references, 12071 HeapIterator heap_iterator;
12072 count = DebugReferencedBy(&heap_iterator,
12073 target, instance_filter, max_references,
12098 NULL, 0, arguments_function); 12074 NULL, 0, arguments_function);
12099 12075
12100 // Allocate an array to hold the result. 12076 // Allocate an array to hold the result.
12101 Object* object; 12077 Object* object;
12102 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); 12078 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
12103 if (!maybe_object->ToObject(&object)) return maybe_object; 12079 if (!maybe_object->ToObject(&object)) return maybe_object;
12104 } 12080 }
12105 FixedArray* instances = FixedArray::cast(object); 12081 FixedArray* instances = FixedArray::cast(object);
12106 12082
12107 // Fill the referencing objects. 12083 // Fill the referencing objects.
12108 count = DebugReferencedBy(target, instance_filter, max_references, 12084 // AllocateFixedArray above does not make the heap non-iterable.
12085 ASSERT(HEAP->IsHeapIterable());
12086 HeapIterator heap_iterator2;
12087 count = DebugReferencedBy(&heap_iterator2,
12088 target, instance_filter, max_references,
12109 instances, count, arguments_function); 12089 instances, count, arguments_function);
12110 12090
12111 // Return result as JS array. 12091 // Return result as JS array.
12112 Object* result; 12092 Object* result;
12113 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12093 MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12114 isolate->context()->global_context()->array_function()); 12094 isolate->context()->global_context()->array_function());
12115 if (!maybe_result->ToObject(&result)) return maybe_result; 12095 if (!maybe_result->ToObject(&result)) return maybe_result;
12116 } 12096 return JSArray::cast(result)->SetContent(instances);
12117 JSArray::cast(result)->SetContent(instances);
12118 return result;
12119 } 12097 }
12120 12098
12121 12099
12122 // Helper function used by Runtime_DebugConstructedBy below. 12100 // Helper function used by Runtime_DebugConstructedBy below.
12123 static int DebugConstructedBy(JSFunction* constructor, int max_references, 12101 static int DebugConstructedBy(HeapIterator* iterator,
12124 FixedArray* instances, int instances_size) { 12102 JSFunction* constructor,
12103 int max_references,
12104 FixedArray* instances,
12105 int instances_size) {
12125 AssertNoAllocation no_alloc; 12106 AssertNoAllocation no_alloc;
12126 12107
12127 // Iterate the heap. 12108 // Iterate the heap.
12128 int count = 0; 12109 int count = 0;
12129 HeapIterator iterator;
12130 HeapObject* heap_obj = NULL; 12110 HeapObject* heap_obj = NULL;
12131 while (((heap_obj = iterator.next()) != NULL) && 12111 while (((heap_obj = iterator->next()) != NULL) &&
12132 (max_references == 0 || count < max_references)) { 12112 (max_references == 0 || count < max_references)) {
12133 // Only look at all JSObjects. 12113 // Only look at all JSObjects.
12134 if (heap_obj->IsJSObject()) { 12114 if (heap_obj->IsJSObject()) {
12135 JSObject* obj = JSObject::cast(heap_obj); 12115 JSObject* obj = JSObject::cast(heap_obj);
12136 if (obj->map()->constructor() == constructor) { 12116 if (obj->map()->constructor() == constructor) {
12137 // Valid reference found add to instance array if supplied an update 12117 // Valid reference found add to instance array if supplied an update
12138 // count. 12118 // count.
12139 if (instances != NULL && count < instances_size) { 12119 if (instances != NULL && count < instances_size) {
12140 instances->set(count, obj); 12120 instances->set(count, obj);
12141 } 12121 }
12142 count++; 12122 count++;
12143 } 12123 }
12144 } 12124 }
12145 } 12125 }
12146 12126
12147 // Return the number of referencing objects found. 12127 // Return the number of referencing objects found.
12148 return count; 12128 return count;
12149 } 12129 }
12150 12130
12151 12131
12152 // Scan the heap for objects constructed by a specific function. 12132 // Scan the heap for objects constructed by a specific function.
12153 // args[0]: the constructor to find instances of 12133 // args[0]: the constructor to find instances of
12154 // args[1]: the the maximum number of objects to return 12134 // args[1]: the the maximum number of objects to return
12155 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { 12135 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
12156 ASSERT(args.length() == 2); 12136 ASSERT(args.length() == 2);
12157 12137
12158 // First perform a full GC in order to avoid dead objects. 12138 // First perform a full GC in order to avoid dead objects.
12159 isolate->heap()->CollectAllGarbage(false); 12139 isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
12160 12140
12161 // Check parameters. 12141 // Check parameters.
12162 CONVERT_CHECKED(JSFunction, constructor, args[0]); 12142 CONVERT_CHECKED(JSFunction, constructor, args[0]);
12163 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); 12143 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
12164 RUNTIME_ASSERT(max_references >= 0); 12144 RUNTIME_ASSERT(max_references >= 0);
12165 12145
12166 // Get the number of referencing objects. 12146 // Get the number of referencing objects.
12167 int count; 12147 int count;
12168 count = DebugConstructedBy(constructor, max_references, NULL, 0); 12148 HeapIterator heap_iterator;
12149 count = DebugConstructedBy(&heap_iterator,
12150 constructor,
12151 max_references,
12152 NULL,
12153 0);
12169 12154
12170 // Allocate an array to hold the result. 12155 // Allocate an array to hold the result.
12171 Object* object; 12156 Object* object;
12172 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); 12157 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
12173 if (!maybe_object->ToObject(&object)) return maybe_object; 12158 if (!maybe_object->ToObject(&object)) return maybe_object;
12174 } 12159 }
12175 FixedArray* instances = FixedArray::cast(object); 12160 FixedArray* instances = FixedArray::cast(object);
12176 12161
12162 ASSERT(HEAP->IsHeapIterable());
12177 // Fill the referencing objects. 12163 // Fill the referencing objects.
12178 count = DebugConstructedBy(constructor, max_references, instances, count); 12164 HeapIterator heap_iterator2;
12165 count = DebugConstructedBy(&heap_iterator2,
12166 constructor,
12167 max_references,
12168 instances,
12169 count);
12179 12170
12180 // Return result as JS array. 12171 // Return result as JS array.
12181 Object* result; 12172 Object* result;
12182 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12173 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12183 isolate->context()->global_context()->array_function()); 12174 isolate->context()->global_context()->array_function());
12184 if (!maybe_result->ToObject(&result)) return maybe_result; 12175 if (!maybe_result->ToObject(&result)) return maybe_result;
12185 } 12176 }
12186 JSArray::cast(result)->SetContent(instances); 12177 return JSArray::cast(result)->SetContent(instances);
12187 return result;
12188 } 12178 }
12189 12179
12190 12180
12191 // Find the effective prototype object as returned by __proto__. 12181 // Find the effective prototype object as returned by __proto__.
12192 // args[0]: the object to find the prototype for. 12182 // args[0]: the object to find the prototype for.
12193 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { 12183 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
12194 ASSERT(args.length() == 1); 12184 ASSERT(args.length() == 1);
12195 12185
12196 CONVERT_CHECKED(JSObject, obj, args[0]); 12186 CONVERT_CHECKED(JSObject, obj, args[0]);
12197 12187
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
12241 12231
12242 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) { 12232 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
12243 NoHandleAllocation ha; 12233 NoHandleAllocation ha;
12244 ASSERT(args.length() == 1); 12234 ASSERT(args.length() == 1);
12245 12235
12246 CONVERT_CHECKED(JSFunction, f, args[0]); 12236 CONVERT_CHECKED(JSFunction, f, args[0]);
12247 return f->shared()->inferred_name(); 12237 return f->shared()->inferred_name();
12248 } 12238 }
12249 12239
12250 12240
12251 static int FindSharedFunctionInfosForScript(Script* script, 12241 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
12242 Script* script,
12252 FixedArray* buffer) { 12243 FixedArray* buffer) {
12253 AssertNoAllocation no_allocations; 12244 AssertNoAllocation no_allocations;
12254
12255 int counter = 0; 12245 int counter = 0;
12256 int buffer_size = buffer->length(); 12246 int buffer_size = buffer->length();
12257 HeapIterator iterator; 12247 for (HeapObject* obj = iterator->next();
12258 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 12248 obj != NULL;
12249 obj = iterator->next()) {
12259 ASSERT(obj != NULL); 12250 ASSERT(obj != NULL);
12260 if (!obj->IsSharedFunctionInfo()) { 12251 if (!obj->IsSharedFunctionInfo()) {
12261 continue; 12252 continue;
12262 } 12253 }
12263 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 12254 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
12264 if (shared->script() != script) { 12255 if (shared->script() != script) {
12265 continue; 12256 continue;
12266 } 12257 }
12267 if (counter < buffer_size) { 12258 if (counter < buffer_size) {
12268 buffer->set(counter, shared); 12259 buffer->set(counter, shared);
12269 } 12260 }
12270 counter++; 12261 counter++;
12271 } 12262 }
12272 return counter; 12263 return counter;
12273 } 12264 }
12274 12265
12275 // For a script finds all SharedFunctionInfo's in the heap that points 12266 // For a script finds all SharedFunctionInfo's in the heap that points
12276 // to this script. Returns JSArray of SharedFunctionInfo wrapped 12267 // to this script. Returns JSArray of SharedFunctionInfo wrapped
12277 // in OpaqueReferences. 12268 // in OpaqueReferences.
12278 RUNTIME_FUNCTION(MaybeObject*, 12269 RUNTIME_FUNCTION(MaybeObject*,
12279 Runtime_LiveEditFindSharedFunctionInfosForScript) { 12270 Runtime_LiveEditFindSharedFunctionInfosForScript) {
12280 ASSERT(args.length() == 1); 12271 ASSERT(args.length() == 1);
12281 HandleScope scope(isolate); 12272 HandleScope scope(isolate);
12282 CONVERT_CHECKED(JSValue, script_value, args[0]); 12273 CONVERT_CHECKED(JSValue, script_value, args[0]);
12283 12274
12275
12284 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); 12276 Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
12285 12277
12286 const int kBufferSize = 32; 12278 const int kBufferSize = 32;
12287 12279
12288 Handle<FixedArray> array; 12280 Handle<FixedArray> array;
12289 array = isolate->factory()->NewFixedArray(kBufferSize); 12281 array = isolate->factory()->NewFixedArray(kBufferSize);
12290 int number = FindSharedFunctionInfosForScript(*script, *array); 12282 int number;
12283 {
12284 isolate->heap()->EnsureHeapIsIterable();
12285 AssertNoAllocation no_allocations;
12286 HeapIterator heap_iterator;
12287 Script* scr = *script;
12288 FixedArray* arr = *array;
12289 number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
12290 }
12291 if (number > kBufferSize) { 12291 if (number > kBufferSize) {
12292 array = isolate->factory()->NewFixedArray(number); 12292 array = isolate->factory()->NewFixedArray(number);
12293 FindSharedFunctionInfosForScript(*script, *array); 12293 isolate->heap()->EnsureHeapIsIterable();
12294 AssertNoAllocation no_allocations;
12295 HeapIterator heap_iterator;
12296 Script* scr = *script;
12297 FixedArray* arr = *array;
12298 FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
12294 } 12299 }
12295 12300
12296 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array); 12301 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
12297 result->set_length(Smi::FromInt(number)); 12302 result->set_length(Smi::FromInt(number));
12298 12303
12299 LiveEdit::WrapSharedFunctionInfos(result); 12304 LiveEdit::WrapSharedFunctionInfos(result);
12300 12305
12301 return *result; 12306 return *result;
12302 } 12307 }
12303 12308
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
12764 // heap traversal to find the function generated for the source position 12769 // heap traversal to find the function generated for the source position
12765 // for the requested break point. For lazily compiled functions several heap 12770 // for the requested break point. For lazily compiled functions several heap
12766 // traversals might be required rendering this operation as a rather slow 12771 // traversals might be required rendering this operation as a rather slow
12767 // operation. However for setting break points which is normally done through 12772 // operation. However for setting break points which is normally done through
12768 // some kind of user interaction the performance is not crucial. 12773 // some kind of user interaction the performance is not crucial.
12769 static Handle<Object> Runtime_GetScriptFromScriptName( 12774 static Handle<Object> Runtime_GetScriptFromScriptName(
12770 Handle<String> script_name) { 12775 Handle<String> script_name) {
12771 // Scan the heap for Script objects to find the script with the requested 12776 // Scan the heap for Script objects to find the script with the requested
12772 // script data. 12777 // script data.
12773 Handle<Script> script; 12778 Handle<Script> script;
12779 script_name->GetHeap()->EnsureHeapIsIterable();
12780 AssertNoAllocation no_allocation_during_heap_iteration;
12774 HeapIterator iterator; 12781 HeapIterator iterator;
12775 HeapObject* obj = NULL; 12782 HeapObject* obj = NULL;
12776 while (script.is_null() && ((obj = iterator.next()) != NULL)) { 12783 while (script.is_null() && ((obj = iterator.next()) != NULL)) {
12777 // If a script is found check if it has the script data requested. 12784 // If a script is found check if it has the script data requested.
12778 if (obj->IsScript()) { 12785 if (obj->IsScript()) {
12779 if (Script::cast(obj)->name()->IsString()) { 12786 if (Script::cast(obj)->name()->IsString()) {
12780 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { 12787 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
12781 script = Handle<Script>(Script::cast(obj)); 12788 script = Handle<Script>(Script::cast(obj));
12782 } 12789 }
12783 } 12790 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
12976 Handle<JSFunctionResultCache> cache_handle(cache); 12983 Handle<JSFunctionResultCache> cache_handle(cache);
12977 Handle<Object> key_handle(key); 12984 Handle<Object> key_handle(key);
12978 Handle<Object> value; 12985 Handle<Object> value;
12979 { 12986 {
12980 Handle<JSFunction> factory(JSFunction::cast( 12987 Handle<JSFunction> factory(JSFunction::cast(
12981 cache_handle->get(JSFunctionResultCache::kFactoryIndex))); 12988 cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
12982 // TODO(antonm): consider passing a receiver when constructing a cache. 12989 // TODO(antonm): consider passing a receiver when constructing a cache.
12983 Handle<Object> receiver(isolate->global_context()->global()); 12990 Handle<Object> receiver(isolate->global_context()->global());
12984 // This handle is nor shared, nor used later, so it's safe. 12991 // This handle is nor shared, nor used later, so it's safe.
12985 Object** argv[] = { key_handle.location() }; 12992 Object** argv[] = { key_handle.location() };
12986 bool pending_exception = false; 12993 bool pending_exception;
12987 value = Execution::Call(factory, 12994 value = Execution::Call(factory,
12988 receiver, 12995 receiver,
12989 1, 12996 1,
12990 argv, 12997 argv,
12991 &pending_exception); 12998 &pending_exception);
12992 if (pending_exception) return Failure::Exception(); 12999 if (pending_exception) return Failure::Exception();
12993 } 13000 }
12994 13001
12995 #ifdef DEBUG 13002 #ifdef DEBUG
12996 cache_handle->JSFunctionResultCacheVerify(); 13003 cache_handle->JSFunctionResultCacheVerify();
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
13132 return NULL; 13139 return NULL;
13133 } 13140 }
13134 13141
13135 13142
13136 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ 13143 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
13137 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ 13144 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
13138 CONVERT_CHECKED(JSObject, obj, args[0]); \ 13145 CONVERT_CHECKED(JSObject, obj, args[0]); \
13139 return isolate->heap()->ToBoolean(obj->Has##Name()); \ 13146 return isolate->heap()->ToBoolean(obj->Has##Name()); \
13140 } 13147 }
13141 13148
13149 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
13142 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) 13150 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
13143 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) 13151 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
13144 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) 13152 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
13145 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) 13153 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
13146 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) 13154 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
13147 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) 13155 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
13148 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) 13156 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
13149 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) 13157 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
13150 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) 13158 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
13151 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) 13159 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
13215 13223
13216 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 13224 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
13217 return &(kIntrinsicFunctions[static_cast<int>(id)]); 13225 return &(kIntrinsicFunctions[static_cast<int>(id)]);
13218 } 13226 }
13219 13227
13220 13228
13221 void Runtime::PerformGC(Object* result) { 13229 void Runtime::PerformGC(Object* result) {
13222 Isolate* isolate = Isolate::Current(); 13230 Isolate* isolate = Isolate::Current();
13223 Failure* failure = Failure::cast(result); 13231 Failure* failure = Failure::cast(result);
13224 if (failure->IsRetryAfterGC()) { 13232 if (failure->IsRetryAfterGC()) {
13233 if (isolate->heap()->new_space()->AddFreshPage()) {
13234 return;
13235 }
13225 // Try to do a garbage collection; ignore it if it fails. The C 13236 // Try to do a garbage collection; ignore it if it fails. The C
13226 // entry stub will throw an out-of-memory exception in that case. 13237 // entry stub will throw an out-of-memory exception in that case.
13227 isolate->heap()->CollectGarbage(failure->allocation_space()); 13238 isolate->heap()->CollectGarbage(failure->allocation_space());
13228 } else { 13239 } else {
13229 // Handle last resort GC and make sure to allow future allocations 13240 // Handle last resort GC and make sure to allow future allocations
13230 // to grow the heap without causing GCs (if possible). 13241 // to grow the heap without causing GCs (if possible).
13231 isolate->counters()->gc_last_resort_from_js()->Increment(); 13242 isolate->counters()->gc_last_resort_from_js()->Increment();
13232 isolate->heap()->CollectAllGarbage(false); 13243 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13233 } 13244 }
13234 } 13245 }
13235 13246
13236 13247
13237 } } // namespace v8::internal 13248 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698