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

Side by Side Diff: src/runtime.cc

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 HandleScope scope(isolate); 687 HandleScope scope(isolate);
688 ASSERT(args.length() == 1); 688 ASSERT(args.length() == 1);
689 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); 689 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
690 JSProxy::Fix(proxy); 690 JSProxy::Fix(proxy);
691 return isolate->heap()->undefined_value(); 691 return isolate->heap()->undefined_value();
692 } 692 }
693 693
694 694
695 void Runtime::FreeArrayBuffer(Isolate* isolate, 695 void Runtime::FreeArrayBuffer(Isolate* isolate,
696 JSArrayBuffer* phantom_array_buffer) { 696 JSArrayBuffer* phantom_array_buffer) {
697 if (phantom_array_buffer->should_be_freed()) {
698 ASSERT(phantom_array_buffer->is_external());
699 free(phantom_array_buffer->backing_store());
700 }
697 if (phantom_array_buffer->is_external()) return; 701 if (phantom_array_buffer->is_external()) return;
698 702
699 size_t allocated_length = NumberToSize( 703 size_t allocated_length = NumberToSize(
700 isolate, phantom_array_buffer->byte_length()); 704 isolate, phantom_array_buffer->byte_length());
701 705
702 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( 706 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
703 -static_cast<intptr_t>(allocated_length)); 707 -static_cast<int64_t>(allocated_length));
704 CHECK(V8::ArrayBufferAllocator() != NULL); 708 CHECK(V8::ArrayBufferAllocator() != NULL);
705 V8::ArrayBufferAllocator()->Free( 709 V8::ArrayBufferAllocator()->Free(
706 phantom_array_buffer->backing_store(), 710 phantom_array_buffer->backing_store(),
707 allocated_length); 711 allocated_length);
708 } 712 }
709 713
710 714
711 void Runtime::SetupArrayBuffer(Isolate* isolate, 715 void Runtime::SetupArrayBuffer(Isolate* isolate,
712 Handle<JSArrayBuffer> array_buffer, 716 Handle<JSArrayBuffer> array_buffer,
713 bool is_external, 717 bool is_external,
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 914
911 holder->set_buffer(*buffer); 915 holder->set_buffer(*buffer);
912 holder->set_byte_offset(*byte_offset_object); 916 holder->set_byte_offset(*byte_offset_object);
913 holder->set_byte_length(*byte_length_object); 917 holder->set_byte_length(*byte_length_object);
914 918
915 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); 919 size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
916 size_t byte_length = NumberToSize(isolate, *byte_length_object); 920 size_t byte_length = NumberToSize(isolate, *byte_length_object);
917 ASSERT(byte_length % element_size == 0); 921 ASSERT(byte_length % element_size == 0);
918 size_t length = byte_length / element_size; 922 size_t length = byte_length / element_size;
919 923
924 if (length > static_cast<unsigned>(Smi::kMaxValue)) {
925 return isolate->Throw(*isolate->factory()->
926 NewRangeError("invalid_typed_array_length",
927 HandleVector<Object>(NULL, 0)));
928 }
929
920 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); 930 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
921 holder->set_length(*length_obj); 931 holder->set_length(*length_obj);
922 holder->set_weak_next(buffer->weak_first_view()); 932 holder->set_weak_next(buffer->weak_first_view());
923 buffer->set_weak_first_view(*holder); 933 buffer->set_weak_first_view(*holder);
924 934
925 Handle<ExternalArray> elements = 935 Handle<ExternalArray> elements =
926 isolate->factory()->NewExternalArray( 936 isolate->factory()->NewExternalArray(
927 static_cast<int>(length), array_type, 937 static_cast<int>(length), array_type,
928 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); 938 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
929 holder->set_elements(*elements); 939 holder->set_elements(*elements);
(...skipping 19 matching lines...) Expand all
949 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { 959 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
950 holder->SetInternalField(i, Smi::FromInt(0)); 960 holder->SetInternalField(i, Smi::FromInt(0));
951 } 961 }
952 962
953 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. 963 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization.
954 size_t element_size = 1; // Bogus initialization. 964 size_t element_size = 1; // Bogus initialization.
955 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size); 965 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
956 966
957 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); 967 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
958 size_t length = NumberToSize(isolate, *length_obj); 968 size_t length = NumberToSize(isolate, *length_obj);
959 size_t byte_length = length * element_size; 969
960 if (byte_length < length) { // Overflow 970 if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
971 (length > (kMaxInt / element_size))) {
961 return isolate->Throw(*isolate->factory()-> 972 return isolate->Throw(*isolate->factory()->
962 NewRangeError("invalid_array_buffer_length", 973 NewRangeError("invalid_typed_array_length",
963 HandleVector<Object>(NULL, 0))); 974 HandleVector<Object>(NULL, 0)));
964 } 975 }
976 size_t byte_length = length * element_size;
965 977
966 // NOTE: not initializing backing store. 978 // NOTE: not initializing backing store.
967 // We assume that the caller of this function will initialize holder 979 // We assume that the caller of this function will initialize holder
968 // with the loop 980 // with the loop
969 // for(i = 0; i < length; i++) { holder[i] = source[i]; } 981 // for(i = 0; i < length; i++) { holder[i] = source[i]; }
970 // We assume that the caller of this function is always a typed array 982 // We assume that the caller of this function is always a typed array
971 // constructor. 983 // constructor.
972 // If source is a typed array, this loop will always run to completion, 984 // If source is a typed array, this loop will always run to completion,
973 // so we are sure that the backing store will be initialized. 985 // so we are sure that the backing store will be initialized.
974 // Otherwise, the indexing operation might throw, so the loop will not 986 // Otherwise, the indexing operation might throw, so the loop will not
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1209 }
1198 1210
1199 1211
1200 template<typename T> 1212 template<typename T>
1201 inline static bool DataViewGetValue( 1213 inline static bool DataViewGetValue(
1202 Isolate* isolate, 1214 Isolate* isolate,
1203 Handle<JSDataView> data_view, 1215 Handle<JSDataView> data_view,
1204 Handle<Object> byte_offset_obj, 1216 Handle<Object> byte_offset_obj,
1205 bool is_little_endian, 1217 bool is_little_endian,
1206 T* result) { 1218 T* result) {
1207 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); 1219 size_t byte_offset = 0;
1220 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1221 return false;
1222 }
1208 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); 1223 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1209 1224
1210 size_t data_view_byte_offset = 1225 size_t data_view_byte_offset =
1211 NumberToSize(isolate, data_view->byte_offset()); 1226 NumberToSize(isolate, data_view->byte_offset());
1212 size_t data_view_byte_length = 1227 size_t data_view_byte_length =
1213 NumberToSize(isolate, data_view->byte_length()); 1228 NumberToSize(isolate, data_view->byte_length());
1214 if (byte_offset + sizeof(T) > data_view_byte_length || 1229 if (byte_offset + sizeof(T) > data_view_byte_length ||
1215 byte_offset + sizeof(T) < byte_offset) { // overflow 1230 byte_offset + sizeof(T) < byte_offset) { // overflow
1216 return false; 1231 return false;
1217 } 1232 }
(...skipping 20 matching lines...) Expand all
1238 } 1253 }
1239 1254
1240 1255
1241 template<typename T> 1256 template<typename T>
1242 static bool DataViewSetValue( 1257 static bool DataViewSetValue(
1243 Isolate* isolate, 1258 Isolate* isolate,
1244 Handle<JSDataView> data_view, 1259 Handle<JSDataView> data_view,
1245 Handle<Object> byte_offset_obj, 1260 Handle<Object> byte_offset_obj,
1246 bool is_little_endian, 1261 bool is_little_endian,
1247 T data) { 1262 T data) {
1248 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); 1263 size_t byte_offset = 0;
1264 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1265 return false;
1266 }
1249 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); 1267 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1250 1268
1251 size_t data_view_byte_offset = 1269 size_t data_view_byte_offset =
1252 NumberToSize(isolate, data_view->byte_offset()); 1270 NumberToSize(isolate, data_view->byte_offset());
1253 size_t data_view_byte_length = 1271 size_t data_view_byte_length =
1254 NumberToSize(isolate, data_view->byte_length()); 1272 NumberToSize(isolate, data_view->byte_length());
1255 if (byte_offset + sizeof(T) > data_view_byte_length || 1273 if (byte_offset + sizeof(T) > data_view_byte_length ||
1256 byte_offset + sizeof(T) < byte_offset) { // overflow 1274 byte_offset + sizeof(T) < byte_offset) { // overflow
1257 return false; 1275 return false;
1258 } 1276 }
(...skipping 6568 matching lines...) Expand 10 before | Expand all | Expand 10 after
7827 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { 7845 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
7828 SealHandleScope shs(isolate); 7846 SealHandleScope shs(isolate);
7829 ASSERT(args.length() == 1); 7847 ASSERT(args.length() == 1);
7830 isolate->counters()->math_tan()->Increment(); 7848 isolate->counters()->math_tan()->Increment();
7831 7849
7832 CONVERT_DOUBLE_ARG_CHECKED(x, 0); 7850 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7833 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); 7851 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
7834 } 7852 }
7835 7853
7836 7854
7837 RUNTIME_FUNCTION(MaybeObject*, Runtime_PopulateTrigonometricTable) {
7838 HandleScope scope(isolate);
7839 ASSERT(args.length() == 3);
7840 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sin_table, 0);
7841 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, cos_table, 1);
7842 CONVERT_SMI_ARG_CHECKED(samples, 2);
7843 RUNTIME_ASSERT(sin_table->type() == kExternalDoubleArray);
7844 RUNTIME_ASSERT(cos_table->type() == kExternalDoubleArray);
7845 double* sin_buffer = reinterpret_cast<double*>(
7846 JSArrayBuffer::cast(sin_table->buffer())->backing_store());
7847 double* cos_buffer = reinterpret_cast<double*>(
7848 JSArrayBuffer::cast(cos_table->buffer())->backing_store());
7849
7850 static const double pi_half = 3.1415926535897932 / 2;
7851 double interval = pi_half / samples;
7852 for (int i = 0; i < samples + 1; i++) {
7853 double sample = sin(i * interval);
7854 sin_buffer[i] = sample;
7855 cos_buffer[samples - i] = sample * interval;
7856 }
7857
7858 // Fill this to catch out of bound accesses when calculating Math.sin(pi/2).
7859 sin_buffer[samples + 1] = sin(pi_half + interval);
7860 cos_buffer[samples + 1] = cos(pi_half + interval) * interval;
7861
7862 return isolate->heap()->undefined_value();
7863 }
7864
7865
7866 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { 7855 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
7867 SealHandleScope shs(isolate); 7856 SealHandleScope shs(isolate);
7868 ASSERT(args.length() == 2); 7857 ASSERT(args.length() == 2);
7869 7858
7870 CONVERT_SMI_ARG_CHECKED(year, 0); 7859 CONVERT_SMI_ARG_CHECKED(year, 0);
7871 CONVERT_SMI_ARG_CHECKED(month, 1); 7860 CONVERT_SMI_ARG_CHECKED(month, 1);
7872 7861
7873 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month)); 7862 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
7874 } 7863 }
7875 7864
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
8403 8392
8404 RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) { 8393 RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) {
8405 HandleScope handle_scope(isolate); 8394 HandleScope handle_scope(isolate);
8406 ASSERT(args.length() == 1); 8395 ASSERT(args.length() == 1);
8407 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8396 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8408 if (!AllowOptimization(isolate, function)) { 8397 if (!AllowOptimization(isolate, function)) {
8409 function->ReplaceCode(function->shared()->code()); 8398 function->ReplaceCode(function->shared()->code());
8410 return isolate->heap()->undefined_value(); 8399 return isolate->heap()->undefined_value();
8411 } 8400 }
8412 function->shared()->code()->set_profiler_ticks(0); 8401 function->shared()->code()->set_profiler_ticks(0);
8413 ASSERT(FLAG_concurrent_recompilation); 8402 ASSERT(isolate->concurrent_recompilation_enabled());
8414 if (!Compiler::RecompileConcurrent(function)) { 8403 if (!Compiler::RecompileConcurrent(function)) {
8415 function->ReplaceCode(function->shared()->code()); 8404 function->ReplaceCode(function->shared()->code());
8416 } 8405 }
8417 return isolate->heap()->undefined_value(); 8406 return isolate->heap()->undefined_value();
8418 } 8407 }
8419 8408
8420 8409
8421 class ActivationsFinder : public ThreadVisitor { 8410 class ActivationsFinder : public ThreadVisitor {
8422 public: 8411 public:
8423 Code* code_; 8412 Code* code_;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
8540 #if defined(USE_SIMULATOR) 8529 #if defined(USE_SIMULATOR)
8541 return isolate->heap()->true_value(); 8530 return isolate->heap()->true_value();
8542 #else 8531 #else
8543 return isolate->heap()->false_value(); 8532 return isolate->heap()->false_value();
8544 #endif 8533 #endif
8545 } 8534 }
8546 8535
8547 8536
8548 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) { 8537 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) {
8549 HandleScope scope(isolate); 8538 HandleScope scope(isolate);
8550 return FLAG_concurrent_recompilation 8539 return isolate->concurrent_recompilation_enabled()
8551 ? isolate->heap()->true_value() : isolate->heap()->false_value(); 8540 ? isolate->heap()->true_value() : isolate->heap()->false_value();
8552 } 8541 }
8553 8542
8554 8543
8555 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) { 8544 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
8556 HandleScope scope(isolate); 8545 HandleScope scope(isolate);
8557 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); 8546 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8558 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8547 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8559 8548
8560 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 8549 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
8598 return Smi::FromInt(4); // 4 == "never". 8587 return Smi::FromInt(4); // 4 == "never".
8599 } 8588 }
8600 bool sync_with_compiler_thread = true; 8589 bool sync_with_compiler_thread = true;
8601 if (args.length() == 2) { 8590 if (args.length() == 2) {
8602 CONVERT_ARG_HANDLE_CHECKED(String, sync, 1); 8591 CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8603 if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) { 8592 if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8604 sync_with_compiler_thread = false; 8593 sync_with_compiler_thread = false;
8605 } 8594 }
8606 } 8595 }
8607 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8596 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8608 if (FLAG_concurrent_recompilation && sync_with_compiler_thread) { 8597 if (isolate->concurrent_recompilation_enabled() &&
8598 sync_with_compiler_thread) {
8609 while (function->IsInRecompileQueue()) { 8599 while (function->IsInRecompileQueue()) {
8610 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); 8600 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8611 OS::Sleep(50); 8601 OS::Sleep(50);
8612 } 8602 }
8613 } 8603 }
8614 if (FLAG_always_opt) { 8604 if (FLAG_always_opt) {
8615 // We may have always opt, but that is more best-effort than a real 8605 // We may have always opt, but that is more best-effort than a real
8616 // promise, so we still say "no" if it is not optimized. 8606 // promise, so we still say "no" if it is not optimized.
8617 return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always". 8607 return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always".
8618 : Smi::FromInt(2); // 2 == "no". 8608 : Smi::FromInt(2); // 2 == "no".
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
8676 ASSERT(pc_offset == 8666 ASSERT(pc_offset ==
8677 static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start())); 8667 static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()));
8678 #endif // DEBUG 8668 #endif // DEBUG
8679 8669
8680 // We're not prepared to handle a function with arguments object. 8670 // We're not prepared to handle a function with arguments object.
8681 ASSERT(!function->shared()->uses_arguments()); 8671 ASSERT(!function->shared()->uses_arguments());
8682 8672
8683 Handle<Code> result = Handle<Code>::null(); 8673 Handle<Code> result = Handle<Code>::null();
8684 BailoutId ast_id = BailoutId::None(); 8674 BailoutId ast_id = BailoutId::None();
8685 8675
8686 if (FLAG_concurrent_osr) { 8676 if (isolate->concurrent_osr_enabled()) {
8687 if (isolate->optimizing_compiler_thread()-> 8677 if (isolate->optimizing_compiler_thread()->
8688 IsQueuedForOSR(function, pc_offset)) { 8678 IsQueuedForOSR(function, pc_offset)) {
8689 // Still waiting for the optimizing compiler thread to finish. Carry on. 8679 // Still waiting for the optimizing compiler thread to finish. Carry on.
8690 if (FLAG_trace_osr) { 8680 if (FLAG_trace_osr) {
8691 PrintF("[COSR - polling recompile tasks for "); 8681 PrintF("[COSR - polling recompile tasks for ");
8692 function->PrintName(); 8682 function->PrintName();
8693 PrintF("]\n"); 8683 PrintF("]\n");
8694 } 8684 }
8695 return NULL; 8685 return NULL;
8696 } 8686 }
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
9427 9417
9428 9418
9429 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) { 9419 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) {
9430 HandleScope scope(isolate); 9420 HandleScope scope(isolate);
9431 ASSERT(args.length() == 0); 9421 ASSERT(args.length() == 0);
9432 return isolate->Throw(*isolate->factory()->NewTypeError( 9422 return isolate->Throw(*isolate->factory()->NewTypeError(
9433 "not_date_object", HandleVector<Object>(NULL, 0))); 9423 "not_date_object", HandleVector<Object>(NULL, 0)));
9434 } 9424 }
9435 9425
9436 9426
9427 RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowMessage) {
9428 HandleScope scope(isolate);
9429 ASSERT(args.length() == 1);
9430 CONVERT_SMI_ARG_CHECKED(message_id, 0);
9431 const char* message = GetBailoutReason(
9432 static_cast<BailoutReason>(message_id));
9433 Handle<Name> message_handle =
9434 isolate->factory()->NewStringFromAscii(CStrVector(message));
9435 return isolate->Throw(*message_handle);
9436 }
9437
9437 9438
9438 RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) { 9439 RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
9439 SealHandleScope shs(isolate); 9440 SealHandleScope shs(isolate);
9440 ASSERT(args.length() == 0); 9441 ASSERT(args.length() == 0);
9441 9442
9442 // First check if this is a real stack overflow. 9443 // First check if this is a real stack overflow.
9443 if (isolate->stack_guard()->IsStackOverflow()) { 9444 if (isolate->stack_guard()->IsStackOverflow()) {
9444 return isolate->StackOverflow(); 9445 return isolate->StackOverflow();
9445 } 9446 }
9446 9447
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
9768 args.at<Object>(2), 9769 args.at<Object>(2),
9769 language_mode, 9770 language_mode,
9770 args.smi_at(4)); 9771 args.smi_at(4));
9771 } 9772 }
9772 9773
9773 9774
9774 // Allocate a block of memory in the given space (filled with a filler). 9775 // Allocate a block of memory in the given space (filled with a filler).
9775 // Used as a fall-back for generated code when the space is full. 9776 // Used as a fall-back for generated code when the space is full.
9776 static MaybeObject* Allocate(Isolate* isolate, 9777 static MaybeObject* Allocate(Isolate* isolate,
9777 int size, 9778 int size,
9779 bool double_align,
9778 AllocationSpace space) { 9780 AllocationSpace space) {
9779 Heap* heap = isolate->heap(); 9781 Heap* heap = isolate->heap();
9780 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); 9782 RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9781 RUNTIME_ASSERT(size > 0); 9783 RUNTIME_ASSERT(size > 0);
9782 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); 9784 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize());
9783 HeapObject* allocation; 9785 HeapObject* allocation;
9784 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space); 9786 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space);
9785 if (!maybe_allocation->To(&allocation)) return maybe_allocation; 9787 if (!maybe_allocation->To(&allocation)) return maybe_allocation;
9786 } 9788 }
9787 #ifdef DEBUG 9789 #ifdef DEBUG
9788 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address()); 9790 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
9789 ASSERT(chunk->owner()->identity() == space); 9791 ASSERT(chunk->owner()->identity() == space);
9790 #endif 9792 #endif
9791 heap->CreateFillerObjectAt(allocation->address(), size); 9793 heap->CreateFillerObjectAt(allocation->address(), size);
9792 return allocation; 9794 return allocation;
9793 } 9795 }
9794 9796
9795 9797
9796 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { 9798 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
9797 SealHandleScope shs(isolate); 9799 SealHandleScope shs(isolate);
9798 ASSERT(args.length() == 1); 9800 ASSERT(args.length() == 1);
9799 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); 9801 CONVERT_SMI_ARG_CHECKED(size, 0);
9800 return Allocate(isolate, size_smi->value(), NEW_SPACE); 9802 return Allocate(isolate, size, false, NEW_SPACE);
9801 } 9803 }
9802 9804
9803 9805
9804 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldPointerSpace) { 9806 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInTargetSpace) {
9805 SealHandleScope shs(isolate); 9807 SealHandleScope shs(isolate);
9806 ASSERT(args.length() == 1); 9808 ASSERT(args.length() == 2);
9807 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); 9809 CONVERT_SMI_ARG_CHECKED(size, 0);
9808 return Allocate(isolate, size_smi->value(), OLD_POINTER_SPACE); 9810 CONVERT_SMI_ARG_CHECKED(flags, 1);
9811 bool double_align = AllocateDoubleAlignFlag::decode(flags);
9812 AllocationSpace space = AllocateTargetSpace::decode(flags);
9813 return Allocate(isolate, size, double_align, space);
9809 } 9814 }
9810 9815
9811 9816
9812 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldDataSpace) {
9813 SealHandleScope shs(isolate);
9814 ASSERT(args.length() == 1);
9815 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
9816 return Allocate(isolate, size_smi->value(), OLD_DATA_SPACE);
9817 }
9818
9819
9820 // Push an object unto an array of objects if it is not already in the 9817 // Push an object unto an array of objects if it is not already in the
9821 // array. Returns true if the element was pushed on the stack and 9818 // array. Returns true if the element was pushed on the stack and
9822 // false otherwise. 9819 // false otherwise.
9823 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { 9820 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
9824 SealHandleScope shs(isolate); 9821 HandleScope scope(isolate);
9825 ASSERT(args.length() == 2); 9822 ASSERT(args.length() == 2);
9826 CONVERT_ARG_CHECKED(JSArray, array, 0); 9823 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
9827 CONVERT_ARG_CHECKED(JSReceiver, element, 1); 9824 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
9828 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); 9825 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
9829 int length = Smi::cast(array->length())->value(); 9826 int length = Smi::cast(array->length())->value();
9830 FixedArray* elements = FixedArray::cast(array->elements()); 9827 FixedArray* elements = FixedArray::cast(array->elements());
9831 for (int i = 0; i < length; i++) { 9828 for (int i = 0; i < length; i++) {
9832 if (elements->get(i) == element) return isolate->heap()->false_value(); 9829 if (elements->get(i) == *element) return isolate->heap()->false_value();
9833 } 9830 }
9834 Object* obj; 9831
9835 // Strict not needed. Used for cycle detection in Array join implementation. 9832 // Strict not needed. Used for cycle detection in Array join implementation.
9836 { MaybeObject* maybe_obj = 9833 RETURN_IF_EMPTY_HANDLE(isolate, JSObject::SetFastElement(array, length,
9837 array->SetFastElement(length, element, kNonStrictMode, true); 9834 element,
9838 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9835 kNonStrictMode,
9839 } 9836 true));
9840 return isolate->heap()->true_value(); 9837 return isolate->heap()->true_value();
9841 } 9838 }
9842 9839
9843 9840
9844 /** 9841 /**
9845 * A simple visitor visits every element of Array's. 9842 * A simple visitor visits every element of Array's.
9846 * The backend storage can be a fixed array for fast elements case, 9843 * The backend storage can be a fixed array for fast elements case,
9847 * or a dictionary for sparse array. Since Dictionary is a subtype 9844 * or a dictionary for sparse array. Since Dictionary is a subtype
9848 * of FixedArray, the class can be used by both fast and slow cases. 9845 * of FixedArray, the class can be used by both fast and slow cases.
9849 * The second parameter of the constructor, fast_elements, specifies 9846 * The second parameter of the constructor, fast_elements, specifies
(...skipping 4831 matching lines...) Expand 10 before | Expand all | Expand 10 after
14681 } else { 14678 } else {
14682 access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) && 14679 access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) &&
14683 isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS); 14680 isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS);
14684 } 14681 }
14685 return isolate->heap()->ToBoolean(access_allowed); 14682 return isolate->heap()->ToBoolean(access_allowed);
14686 } 14683 }
14687 14684
14688 14685
14689 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, 14686 static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
14690 Handle<JSFunction> constructor, 14687 Handle<JSFunction> constructor,
14691 Handle<Object> type_info, 14688 Handle<AllocationSite> site,
14692 Arguments* caller_args) { 14689 Arguments* caller_args) {
14693 bool holey = false; 14690 bool holey = false;
14694 bool can_use_type_feedback = true; 14691 bool can_use_type_feedback = true;
14695 if (caller_args->length() == 1) { 14692 if (caller_args->length() == 1) {
14696 Object* argument_one = (*caller_args)[0]; 14693 Object* argument_one = (*caller_args)[0];
14697 if (argument_one->IsSmi()) { 14694 if (argument_one->IsSmi()) {
14698 int value = Smi::cast(argument_one)->value(); 14695 int value = Smi::cast(argument_one)->value();
14699 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { 14696 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
14700 // the array is a dictionary in this case. 14697 // the array is a dictionary in this case.
14701 can_use_type_feedback = false; 14698 can_use_type_feedback = false;
14702 } else if (value != 0) { 14699 } else if (value != 0) {
14703 holey = true; 14700 holey = true;
14704 } 14701 }
14705 } else { 14702 } else {
14706 // Non-smi length argument produces a dictionary 14703 // Non-smi length argument produces a dictionary
14707 can_use_type_feedback = false; 14704 can_use_type_feedback = false;
14708 } 14705 }
14709 } 14706 }
14710 14707
14711 JSArray* array; 14708 JSArray* array;
14712 MaybeObject* maybe_array; 14709 MaybeObject* maybe_array;
14713 if (!type_info.is_null() && 14710 if (!site.is_null() && can_use_type_feedback) {
14714 *type_info != isolate->heap()->undefined_value() &&
14715 Cell::cast(*type_info)->value()->IsAllocationSite() &&
14716 can_use_type_feedback) {
14717 Handle<Cell> cell = Handle<Cell>::cast(type_info);
14718 Handle<AllocationSite> site = Handle<AllocationSite>(
14719 AllocationSite::cast(cell->value()), isolate);
14720 ASSERT(!site->SitePointsToLiteral());
14721 ElementsKind to_kind = site->GetElementsKind(); 14711 ElementsKind to_kind = site->GetElementsKind();
14722 if (holey && !IsFastHoleyElementsKind(to_kind)) { 14712 if (holey && !IsFastHoleyElementsKind(to_kind)) {
14723 to_kind = GetHoleyElementsKind(to_kind); 14713 to_kind = GetHoleyElementsKind(to_kind);
14724 // Update the allocation site info to reflect the advice alteration. 14714 // Update the allocation site info to reflect the advice alteration.
14725 site->SetElementsKind(to_kind); 14715 site->SetElementsKind(to_kind);
14726 } 14716 }
14727 14717
14728 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( 14718 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
14729 *constructor, site); 14719 *constructor, site);
14730 if (!maybe_array->To(&array)) return maybe_array; 14720 if (!maybe_array->To(&array)) return maybe_array;
14731 } else { 14721 } else {
14732 maybe_array = isolate->heap()->AllocateJSObject(*constructor); 14722 maybe_array = isolate->heap()->AllocateJSObject(*constructor);
14733 if (!maybe_array->To(&array)) return maybe_array; 14723 if (!maybe_array->To(&array)) return maybe_array;
14734 // We might need to transition to holey 14724 // We might need to transition to holey
14735 ElementsKind kind = constructor->initial_map()->elements_kind(); 14725 ElementsKind kind = constructor->initial_map()->elements_kind();
14736 if (holey && !IsFastHoleyElementsKind(kind)) { 14726 if (holey && !IsFastHoleyElementsKind(kind)) {
14737 kind = GetHoleyElementsKind(kind); 14727 kind = GetHoleyElementsKind(kind);
14738 maybe_array = array->TransitionElementsKind(kind); 14728 maybe_array = array->TransitionElementsKind(kind);
14739 if (maybe_array->IsFailure()) return maybe_array; 14729 if (maybe_array->IsFailure()) return maybe_array;
14740 } 14730 }
14741 } 14731 }
14742 14732
14743 maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0, 14733 maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
14744 DONT_INITIALIZE_ARRAY_ELEMENTS); 14734 DONT_INITIALIZE_ARRAY_ELEMENTS);
14745 if (maybe_array->IsFailure()) return maybe_array; 14735 if (maybe_array->IsFailure()) return maybe_array;
14736 ElementsKind old_kind = array->GetElementsKind();
14746 maybe_array = ArrayConstructInitializeElements(array, caller_args); 14737 maybe_array = ArrayConstructInitializeElements(array, caller_args);
14747 if (maybe_array->IsFailure()) return maybe_array; 14738 if (maybe_array->IsFailure()) return maybe_array;
14739 if (!site.is_null() &&
14740 (old_kind != array->GetElementsKind() ||
14741 !can_use_type_feedback)) {
14742 // The arguments passed in caused a transition. This kind of complexity
14743 // can't be dealt with in the inlined hydrogen array constructor case.
14744 // We must mark the allocationsite as un-inlinable.
14745 site->SetDoNotInlineCall();
14746 }
14748 return array; 14747 return array;
14749 } 14748 }
14750 14749
14751 14750
14752 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { 14751 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
14753 HandleScope scope(isolate); 14752 HandleScope scope(isolate);
14754 // If we get 2 arguments then they are the stub parameters (constructor, type 14753 // If we get 2 arguments then they are the stub parameters (constructor, type
14755 // info). If we get 4, then the first one is a pointer to the arguments 14754 // info). If we get 4, then the first one is a pointer to the arguments
14756 // passed by the caller, and the last one is the length of the arguments 14755 // passed by the caller, and the last one is the length of the arguments
14757 // passed to the caller (redundant, but useful to check on the deoptimizer 14756 // passed to the caller (redundant, but useful to check on the deoptimizer
14758 // with an assert). 14757 // with an assert).
14759 Arguments empty_args(0, NULL); 14758 Arguments empty_args(0, NULL);
14760 bool no_caller_args = args.length() == 2; 14759 bool no_caller_args = args.length() == 2;
14761 ASSERT(no_caller_args || args.length() == 4); 14760 ASSERT(no_caller_args || args.length() == 4);
14762 int parameters_start = no_caller_args ? 0 : 1; 14761 int parameters_start = no_caller_args ? 0 : 1;
14763 Arguments* caller_args = no_caller_args 14762 Arguments* caller_args = no_caller_args
14764 ? &empty_args 14763 ? &empty_args
14765 : reinterpret_cast<Arguments*>(args[0]); 14764 : reinterpret_cast<Arguments*>(args[0]);
14766 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); 14765 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14767 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); 14766 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
14768 #ifdef DEBUG 14767 #ifdef DEBUG
14769 if (!no_caller_args) { 14768 if (!no_caller_args) {
14770 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2); 14769 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
14771 ASSERT(arg_count == caller_args->length()); 14770 ASSERT(arg_count == caller_args->length());
14772 } 14771 }
14773 #endif 14772 #endif
14773
14774 Handle<AllocationSite> site;
14775 if (!type_info.is_null() &&
14776 *type_info != isolate->heap()->undefined_value() &&
14777 Cell::cast(*type_info)->value()->IsAllocationSite()) {
14778 site = Handle<AllocationSite>(
14779 AllocationSite::cast(Cell::cast(*type_info)->value()), isolate);
14780 ASSERT(!site->SitePointsToLiteral());
14781 }
14782
14774 return ArrayConstructorCommon(isolate, 14783 return ArrayConstructorCommon(isolate,
14775 constructor, 14784 constructor,
14776 type_info, 14785 site,
14777 caller_args); 14786 caller_args);
14778 } 14787 }
14779 14788
14780 14789
14781 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { 14790 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
14782 HandleScope scope(isolate); 14791 HandleScope scope(isolate);
14783 Arguments empty_args(0, NULL); 14792 Arguments empty_args(0, NULL);
14784 bool no_caller_args = args.length() == 1; 14793 bool no_caller_args = args.length() == 1;
14785 ASSERT(no_caller_args || args.length() == 3); 14794 ASSERT(no_caller_args || args.length() == 3);
14786 int parameters_start = no_caller_args ? 0 : 1; 14795 int parameters_start = no_caller_args ? 0 : 1;
14787 Arguments* caller_args = no_caller_args 14796 Arguments* caller_args = no_caller_args
14788 ? &empty_args 14797 ? &empty_args
14789 : reinterpret_cast<Arguments*>(args[0]); 14798 : reinterpret_cast<Arguments*>(args[0]);
14790 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); 14799 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14791 #ifdef DEBUG 14800 #ifdef DEBUG
14792 if (!no_caller_args) { 14801 if (!no_caller_args) {
14793 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1); 14802 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
14794 ASSERT(arg_count == caller_args->length()); 14803 ASSERT(arg_count == caller_args->length());
14795 } 14804 }
14796 #endif 14805 #endif
14797 return ArrayConstructorCommon(isolate, 14806 return ArrayConstructorCommon(isolate,
14798 constructor, 14807 constructor,
14799 Handle<Object>::null(), 14808 Handle<AllocationSite>::null(),
14800 caller_args); 14809 caller_args);
14801 } 14810 }
14802 14811
14803 14812
14813 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) {
14814 return Smi::FromInt(Smi::kMaxValue);
14815 }
14816
14817
14804 // ---------------------------------------------------------------------------- 14818 // ----------------------------------------------------------------------------
14805 // Implementation of Runtime 14819 // Implementation of Runtime
14806 14820
14807 #define F(name, number_of_args, result_size) \ 14821 #define F(name, number_of_args, result_size) \
14808 { Runtime::k##name, Runtime::RUNTIME, #name, \ 14822 { Runtime::k##name, Runtime::RUNTIME, #name, \
14809 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, 14823 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
14810 14824
14811 14825
14812 #define I(name, number_of_args, result_size) \ 14826 #define I(name, number_of_args, result_size) \
14813 { Runtime::kInline##name, Runtime::INLINE, \ 14827 { Runtime::kInline##name, Runtime::INLINE, \
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
14878 // Handle last resort GC and make sure to allow future allocations 14892 // Handle last resort GC and make sure to allow future allocations
14879 // to grow the heap without causing GCs (if possible). 14893 // to grow the heap without causing GCs (if possible).
14880 isolate->counters()->gc_last_resort_from_js()->Increment(); 14894 isolate->counters()->gc_last_resort_from_js()->Increment();
14881 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14895 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14882 "Runtime::PerformGC"); 14896 "Runtime::PerformGC");
14883 } 14897 }
14884 } 14898 }
14885 14899
14886 14900
14887 } } // namespace v8::internal 14901 } } // namespace v8::internal
OLDNEW
« include/v8-platform.h ('K') | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698