OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/base/once.h" | 9 #include "src/base/once.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 namespace { | 24 namespace { |
25 | 25 |
26 // Arguments object passed to C++ builtins. | 26 // Arguments object passed to C++ builtins. |
27 template <BuiltinExtraArguments extra_args> | 27 template <BuiltinExtraArguments extra_args> |
28 class BuiltinArguments : public Arguments { | 28 class BuiltinArguments : public Arguments { |
29 public: | 29 public: |
30 BuiltinArguments(int length, Object** arguments) | 30 BuiltinArguments(int length, Object** arguments) |
31 : Arguments(length, arguments) { } | 31 : Arguments(length, arguments) { } |
32 | 32 |
33 Object*& operator[] (int index) { | 33 Object*& operator[] (int index) { |
34 ASSERT(index < length()); | 34 DCHECK(index < length()); |
35 return Arguments::operator[](index); | 35 return Arguments::operator[](index); |
36 } | 36 } |
37 | 37 |
38 template <class S> Handle<S> at(int index) { | 38 template <class S> Handle<S> at(int index) { |
39 ASSERT(index < length()); | 39 DCHECK(index < length()); |
40 return Arguments::at<S>(index); | 40 return Arguments::at<S>(index); |
41 } | 41 } |
42 | 42 |
43 Handle<Object> receiver() { | 43 Handle<Object> receiver() { |
44 return Arguments::at<Object>(0); | 44 return Arguments::at<Object>(0); |
45 } | 45 } |
46 | 46 |
47 Handle<JSFunction> called_function() { | 47 Handle<JSFunction> called_function() { |
48 STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); | 48 STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); |
49 return Arguments::at<JSFunction>(Arguments::length() - 1); | 49 return Arguments::at<JSFunction>(Arguments::length() - 1); |
50 } | 50 } |
51 | 51 |
52 // Gets the total number of arguments including the receiver (but | 52 // Gets the total number of arguments including the receiver (but |
53 // excluding extra arguments). | 53 // excluding extra arguments). |
54 int length() const { | 54 int length() const { |
55 STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); | 55 STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
56 return Arguments::length(); | 56 return Arguments::length(); |
57 } | 57 } |
58 | 58 |
59 #ifdef DEBUG | 59 #ifdef DEBUG |
60 void Verify() { | 60 void Verify() { |
61 // Check we have at least the receiver. | 61 // Check we have at least the receiver. |
62 ASSERT(Arguments::length() >= 1); | 62 DCHECK(Arguments::length() >= 1); |
63 } | 63 } |
64 #endif | 64 #endif |
65 }; | 65 }; |
66 | 66 |
67 | 67 |
68 // Specialize BuiltinArguments for the called function extra argument. | 68 // Specialize BuiltinArguments for the called function extra argument. |
69 | 69 |
70 template <> | 70 template <> |
71 int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const { | 71 int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const { |
72 return Arguments::length() - 1; | 72 return Arguments::length() - 1; |
73 } | 73 } |
74 | 74 |
75 #ifdef DEBUG | 75 #ifdef DEBUG |
76 template <> | 76 template <> |
77 void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() { | 77 void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() { |
78 // Check we have at least the receiver and the called function. | 78 // Check we have at least the receiver and the called function. |
79 ASSERT(Arguments::length() >= 2); | 79 DCHECK(Arguments::length() >= 2); |
80 // Make sure cast to JSFunction succeeds. | 80 // Make sure cast to JSFunction succeeds. |
81 called_function(); | 81 called_function(); |
82 } | 82 } |
83 #endif | 83 #endif |
84 | 84 |
85 | 85 |
86 #define DEF_ARG_TYPE(name, spec) \ | 86 #define DEF_ARG_TYPE(name, spec) \ |
87 typedef BuiltinArguments<spec> name##ArgumentsType; | 87 typedef BuiltinArguments<spec> name##ArgumentsType; |
88 BUILTIN_LIST_C(DEF_ARG_TYPE) | 88 BUILTIN_LIST_C(DEF_ARG_TYPE) |
89 #undef DEF_ARG_TYPE | 89 #undef DEF_ARG_TYPE |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 name##ArgumentsType args, Isolate* isolate) | 131 name##ArgumentsType args, Isolate* isolate) |
132 #endif | 132 #endif |
133 | 133 |
134 | 134 |
135 #ifdef DEBUG | 135 #ifdef DEBUG |
136 static inline bool CalledAsConstructor(Isolate* isolate) { | 136 static inline bool CalledAsConstructor(Isolate* isolate) { |
137 // Calculate the result using a full stack frame iterator and check | 137 // Calculate the result using a full stack frame iterator and check |
138 // that the state of the stack is as we assume it to be in the | 138 // that the state of the stack is as we assume it to be in the |
139 // code below. | 139 // code below. |
140 StackFrameIterator it(isolate); | 140 StackFrameIterator it(isolate); |
141 ASSERT(it.frame()->is_exit()); | 141 DCHECK(it.frame()->is_exit()); |
142 it.Advance(); | 142 it.Advance(); |
143 StackFrame* frame = it.frame(); | 143 StackFrame* frame = it.frame(); |
144 bool reference_result = frame->is_construct(); | 144 bool reference_result = frame->is_construct(); |
145 Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); | 145 Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); |
146 // Because we know fp points to an exit frame we can use the relevant | 146 // Because we know fp points to an exit frame we can use the relevant |
147 // part of ExitFrame::ComputeCallerState directly. | 147 // part of ExitFrame::ComputeCallerState directly. |
148 const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; | 148 const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; |
149 Address caller_fp = Memory::Address_at(fp + kCallerOffset); | 149 Address caller_fp = Memory::Address_at(fp + kCallerOffset); |
150 // This inlines the part of StackFrame::ComputeType that grabs the | 150 // This inlines the part of StackFrame::ComputeType that grabs the |
151 // type of the current frame. Note that StackFrame::ComputeType | 151 // type of the current frame. Note that StackFrame::ComputeType |
152 // has been specialized for each architecture so if any one of them | 152 // has been specialized for each architecture so if any one of them |
153 // changes this code has to be changed as well. | 153 // changes this code has to be changed as well. |
154 const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; | 154 const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; |
155 const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); | 155 const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); |
156 Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); | 156 Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); |
157 bool result = (marker == kConstructMarker); | 157 bool result = (marker == kConstructMarker); |
158 ASSERT_EQ(result, reference_result); | 158 DCHECK_EQ(result, reference_result); |
159 return result; | 159 return result; |
160 } | 160 } |
161 #endif | 161 #endif |
162 | 162 |
163 | 163 |
164 // ---------------------------------------------------------------------------- | 164 // ---------------------------------------------------------------------------- |
165 | 165 |
166 BUILTIN(Illegal) { | 166 BUILTIN(Illegal) { |
167 UNREACHABLE(); | 167 UNREACHABLE(); |
168 return isolate->heap()->undefined_value(); // Make compiler happy. | 168 return isolate->heap()->undefined_value(); // Make compiler happy. |
169 } | 169 } |
170 | 170 |
171 | 171 |
172 BUILTIN(EmptyFunction) { | 172 BUILTIN(EmptyFunction) { |
173 return isolate->heap()->undefined_value(); | 173 return isolate->heap()->undefined_value(); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, | 177 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, |
178 FixedDoubleArray* src, int src_index, int len) { | 178 FixedDoubleArray* src, int src_index, int len) { |
179 if (len == 0) return; | 179 if (len == 0) return; |
180 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, | 180 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, |
181 len * kDoubleSize); | 181 len * kDoubleSize); |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 static FixedArrayBase* LeftTrimFixedArray(Heap* heap, | 185 static FixedArrayBase* LeftTrimFixedArray(Heap* heap, |
186 FixedArrayBase* elms, | 186 FixedArrayBase* elms, |
187 int to_trim) { | 187 int to_trim) { |
188 ASSERT(heap->CanMoveObjectStart(elms)); | 188 DCHECK(heap->CanMoveObjectStart(elms)); |
189 | 189 |
190 Map* map = elms->map(); | 190 Map* map = elms->map(); |
191 int entry_size; | 191 int entry_size; |
192 if (elms->IsFixedArray()) { | 192 if (elms->IsFixedArray()) { |
193 entry_size = kPointerSize; | 193 entry_size = kPointerSize; |
194 } else { | 194 } else { |
195 entry_size = kDoubleSize; | 195 entry_size = kDoubleSize; |
196 } | 196 } |
197 ASSERT(elms->map() != heap->fixed_cow_array_map()); | 197 DCHECK(elms->map() != heap->fixed_cow_array_map()); |
198 // For now this trick is only applied to fixed arrays in new and paged space. | 198 // For now this trick is only applied to fixed arrays in new and paged space. |
199 // In large object space the object's start must coincide with chunk | 199 // In large object space the object's start must coincide with chunk |
200 // and thus the trick is just not applicable. | 200 // and thus the trick is just not applicable. |
201 ASSERT(!heap->lo_space()->Contains(elms)); | 201 DCHECK(!heap->lo_space()->Contains(elms)); |
202 | 202 |
203 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); | 203 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); |
204 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); | 204 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); |
205 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); | 205 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); |
206 | 206 |
207 Object** former_start = HeapObject::RawField(elms, 0); | 207 Object** former_start = HeapObject::RawField(elms, 0); |
208 | 208 |
209 const int len = elms->length(); | 209 const int len = elms->length(); |
210 | 210 |
211 if (to_trim * entry_size > FixedArrayBase::kHeaderSize && | 211 if (to_trim * entry_size > FixedArrayBase::kHeaderSize && |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 } else { | 295 } else { |
296 return MaybeHandle<FixedArrayBase>(); | 296 return MaybeHandle<FixedArrayBase>(); |
297 } | 297 } |
298 | 298 |
299 // Need to ensure that the arguments passed in args can be contained in | 299 // Need to ensure that the arguments passed in args can be contained in |
300 // the array. | 300 // the array. |
301 int args_length = args->length(); | 301 int args_length = args->length(); |
302 if (first_added_arg >= args_length) return handle(array->elements(), isolate); | 302 if (first_added_arg >= args_length) return handle(array->elements(), isolate); |
303 | 303 |
304 ElementsKind origin_kind = array->map()->elements_kind(); | 304 ElementsKind origin_kind = array->map()->elements_kind(); |
305 ASSERT(!IsFastObjectElementsKind(origin_kind)); | 305 DCHECK(!IsFastObjectElementsKind(origin_kind)); |
306 ElementsKind target_kind = origin_kind; | 306 ElementsKind target_kind = origin_kind; |
307 { | 307 { |
308 DisallowHeapAllocation no_gc; | 308 DisallowHeapAllocation no_gc; |
309 int arg_count = args->length() - first_added_arg; | 309 int arg_count = args->length() - first_added_arg; |
310 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); | 310 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); |
311 for (int i = 0; i < arg_count; i++) { | 311 for (int i = 0; i < arg_count; i++) { |
312 Object* arg = arguments[i]; | 312 Object* arg = arguments[i]; |
313 if (arg->IsHeapObject()) { | 313 if (arg->IsHeapObject()) { |
314 if (arg->IsHeapNumber()) { | 314 if (arg->IsHeapNumber()) { |
315 target_kind = FAST_DOUBLE_ELEMENTS; | 315 target_kind = FAST_DOUBLE_ELEMENTS; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 if (!maybe_elms_obj.ToHandle(&elms_obj)) { | 378 if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
379 return CallJsBuiltin(isolate, "ArrayPush", args); | 379 return CallJsBuiltin(isolate, "ArrayPush", args); |
380 } | 380 } |
381 | 381 |
382 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 382 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
383 int len = Smi::cast(array->length())->value(); | 383 int len = Smi::cast(array->length())->value(); |
384 int to_add = args.length() - 1; | 384 int to_add = args.length() - 1; |
385 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { | 385 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { |
386 return CallJsBuiltin(isolate, "ArrayPush", args); | 386 return CallJsBuiltin(isolate, "ArrayPush", args); |
387 } | 387 } |
388 ASSERT(!array->map()->is_observed()); | 388 DCHECK(!array->map()->is_observed()); |
389 | 389 |
390 ElementsKind kind = array->GetElementsKind(); | 390 ElementsKind kind = array->GetElementsKind(); |
391 | 391 |
392 if (IsFastSmiOrObjectElementsKind(kind)) { | 392 if (IsFastSmiOrObjectElementsKind(kind)) { |
393 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 393 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
394 if (to_add == 0) { | 394 if (to_add == 0) { |
395 return Smi::FromInt(len); | 395 return Smi::FromInt(len); |
396 } | 396 } |
397 // Currently fixed arrays cannot grow too big, so | 397 // Currently fixed arrays cannot grow too big, so |
398 // we should never hit this case. | 398 // we should never hit this case. |
399 ASSERT(to_add <= (Smi::kMaxValue - len)); | 399 DCHECK(to_add <= (Smi::kMaxValue - len)); |
400 | 400 |
401 int new_length = len + to_add; | 401 int new_length = len + to_add; |
402 | 402 |
403 if (new_length > elms->length()) { | 403 if (new_length > elms->length()) { |
404 // New backing storage is needed. | 404 // New backing storage is needed. |
405 int capacity = new_length + (new_length >> 1) + 16; | 405 int capacity = new_length + (new_length >> 1) + 16; |
406 Handle<FixedArray> new_elms = | 406 Handle<FixedArray> new_elms = |
407 isolate->factory()->NewUninitializedFixedArray(capacity); | 407 isolate->factory()->NewUninitializedFixedArray(capacity); |
408 | 408 |
409 ElementsAccessor* accessor = array->GetElementsAccessor(); | 409 ElementsAccessor* accessor = array->GetElementsAccessor(); |
(...skipping 18 matching lines...) Expand all Loading... |
428 // Set the length. | 428 // Set the length. |
429 array->set_length(Smi::FromInt(new_length)); | 429 array->set_length(Smi::FromInt(new_length)); |
430 return Smi::FromInt(new_length); | 430 return Smi::FromInt(new_length); |
431 } else { | 431 } else { |
432 int elms_len = elms_obj->length(); | 432 int elms_len = elms_obj->length(); |
433 if (to_add == 0) { | 433 if (to_add == 0) { |
434 return Smi::FromInt(len); | 434 return Smi::FromInt(len); |
435 } | 435 } |
436 // Currently fixed arrays cannot grow too big, so | 436 // Currently fixed arrays cannot grow too big, so |
437 // we should never hit this case. | 437 // we should never hit this case. |
438 ASSERT(to_add <= (Smi::kMaxValue - len)); | 438 DCHECK(to_add <= (Smi::kMaxValue - len)); |
439 | 439 |
440 int new_length = len + to_add; | 440 int new_length = len + to_add; |
441 | 441 |
442 Handle<FixedDoubleArray> new_elms; | 442 Handle<FixedDoubleArray> new_elms; |
443 | 443 |
444 if (new_length > elms_len) { | 444 if (new_length > elms_len) { |
445 // New backing storage is needed. | 445 // New backing storage is needed. |
446 int capacity = new_length + (new_length >> 1) + 16; | 446 int capacity = new_length + (new_length >> 1) + 16; |
447 // Create new backing store; since capacity > 0, we can | 447 // Create new backing store; since capacity > 0, we can |
448 // safely cast to FixedDoubleArray. | 448 // safely cast to FixedDoubleArray. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 HandleScope scope(isolate); | 483 HandleScope scope(isolate); |
484 Handle<Object> receiver = args.receiver(); | 484 Handle<Object> receiver = args.receiver(); |
485 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 485 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
486 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 486 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
487 Handle<FixedArrayBase> elms_obj; | 487 Handle<FixedArrayBase> elms_obj; |
488 if (!maybe_elms_obj.ToHandle(&elms_obj)) { | 488 if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
489 return CallJsBuiltin(isolate, "ArrayPop", args); | 489 return CallJsBuiltin(isolate, "ArrayPop", args); |
490 } | 490 } |
491 | 491 |
492 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 492 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
493 ASSERT(!array->map()->is_observed()); | 493 DCHECK(!array->map()->is_observed()); |
494 | 494 |
495 int len = Smi::cast(array->length())->value(); | 495 int len = Smi::cast(array->length())->value(); |
496 if (len == 0) return isolate->heap()->undefined_value(); | 496 if (len == 0) return isolate->heap()->undefined_value(); |
497 | 497 |
498 ElementsAccessor* accessor = array->GetElementsAccessor(); | 498 ElementsAccessor* accessor = array->GetElementsAccessor(); |
499 int new_length = len - 1; | 499 int new_length = len - 1; |
500 Handle<Object> element = | 500 Handle<Object> element = |
501 accessor->Get(array, array, new_length, elms_obj).ToHandleChecked(); | 501 accessor->Get(array, array, new_length, elms_obj).ToHandleChecked(); |
502 if (element->IsTheHole()) { | 502 if (element->IsTheHole()) { |
503 return CallJsBuiltin(isolate, "ArrayPop", args); | 503 return CallJsBuiltin(isolate, "ArrayPop", args); |
(...skipping 11 matching lines...) Expand all Loading... |
515 Handle<Object> receiver = args.receiver(); | 515 Handle<Object> receiver = args.receiver(); |
516 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 516 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
517 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 517 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
518 Handle<FixedArrayBase> elms_obj; | 518 Handle<FixedArrayBase> elms_obj; |
519 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 519 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
520 !IsJSArrayFastElementMovingAllowed(heap, | 520 !IsJSArrayFastElementMovingAllowed(heap, |
521 *Handle<JSArray>::cast(receiver))) { | 521 *Handle<JSArray>::cast(receiver))) { |
522 return CallJsBuiltin(isolate, "ArrayShift", args); | 522 return CallJsBuiltin(isolate, "ArrayShift", args); |
523 } | 523 } |
524 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 524 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
525 ASSERT(!array->map()->is_observed()); | 525 DCHECK(!array->map()->is_observed()); |
526 | 526 |
527 int len = Smi::cast(array->length())->value(); | 527 int len = Smi::cast(array->length())->value(); |
528 if (len == 0) return heap->undefined_value(); | 528 if (len == 0) return heap->undefined_value(); |
529 | 529 |
530 // Get first element | 530 // Get first element |
531 ElementsAccessor* accessor = array->GetElementsAccessor(); | 531 ElementsAccessor* accessor = array->GetElementsAccessor(); |
532 Handle<Object> first = | 532 Handle<Object> first = |
533 accessor->Get(array, array, 0, elms_obj).ToHandleChecked(); | 533 accessor->Get(array, array, 0, elms_obj).ToHandleChecked(); |
534 if (first->IsTheHole()) { | 534 if (first->IsTheHole()) { |
535 return CallJsBuiltin(isolate, "ArrayShift", args); | 535 return CallJsBuiltin(isolate, "ArrayShift", args); |
(...skipping 28 matching lines...) Expand all Loading... |
564 Handle<Object> receiver = args.receiver(); | 564 Handle<Object> receiver = args.receiver(); |
565 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 565 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
566 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 566 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
567 Handle<FixedArrayBase> elms_obj; | 567 Handle<FixedArrayBase> elms_obj; |
568 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 568 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
569 !IsJSArrayFastElementMovingAllowed(heap, | 569 !IsJSArrayFastElementMovingAllowed(heap, |
570 *Handle<JSArray>::cast(receiver))) { | 570 *Handle<JSArray>::cast(receiver))) { |
571 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 571 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
572 } | 572 } |
573 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 573 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
574 ASSERT(!array->map()->is_observed()); | 574 DCHECK(!array->map()->is_observed()); |
575 if (!array->HasFastSmiOrObjectElements()) { | 575 if (!array->HasFastSmiOrObjectElements()) { |
576 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 576 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
577 } | 577 } |
578 int len = Smi::cast(array->length())->value(); | 578 int len = Smi::cast(array->length())->value(); |
579 int to_add = args.length() - 1; | 579 int to_add = args.length() - 1; |
580 int new_length = len + to_add; | 580 int new_length = len + to_add; |
581 // Currently fixed arrays cannot grow too big, so | 581 // Currently fixed arrays cannot grow too big, so |
582 // we should never hit this case. | 582 // we should never hit this case. |
583 ASSERT(to_add <= (Smi::kMaxValue - len)); | 583 DCHECK(to_add <= (Smi::kMaxValue - len)); |
584 | 584 |
585 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { | 585 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { |
586 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 586 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
587 } | 587 } |
588 | 588 |
589 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 589 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
590 | 590 |
591 JSObject::EnsureCanContainElements(array, &args, 1, to_add, | 591 JSObject::EnsureCanContainElements(array, &args, 1, to_add, |
592 DONT_ALLOW_DOUBLE_ELEMENTS); | 592 DONT_ALLOW_DOUBLE_ELEMENTS); |
593 | 593 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 AllowHeapAllocation allow_allocation; | 670 AllowHeapAllocation allow_allocation; |
671 return CallJsBuiltin(isolate, "ArraySlice", args); | 671 return CallJsBuiltin(isolate, "ArraySlice", args); |
672 } | 672 } |
673 len = Smi::cast(len_obj)->value(); | 673 len = Smi::cast(len_obj)->value(); |
674 if (len > object->elements()->length()) { | 674 if (len > object->elements()->length()) { |
675 AllowHeapAllocation allow_allocation; | 675 AllowHeapAllocation allow_allocation; |
676 return CallJsBuiltin(isolate, "ArraySlice", args); | 676 return CallJsBuiltin(isolate, "ArraySlice", args); |
677 } | 677 } |
678 } | 678 } |
679 | 679 |
680 ASSERT(len >= 0); | 680 DCHECK(len >= 0); |
681 int n_arguments = args.length() - 1; | 681 int n_arguments = args.length() - 1; |
682 | 682 |
683 // Note carefully choosen defaults---if argument is missing, | 683 // Note carefully choosen defaults---if argument is missing, |
684 // it's undefined which gets converted to 0 for relative_start | 684 // it's undefined which gets converted to 0 for relative_start |
685 // and to len for relative_end. | 685 // and to len for relative_end. |
686 relative_start = 0; | 686 relative_start = 0; |
687 relative_end = len; | 687 relative_end = len; |
688 if (n_arguments > 0) { | 688 if (n_arguments > 0) { |
689 Object* arg1 = args[1]; | 689 Object* arg1 = args[1]; |
690 if (arg1->IsSmi()) { | 690 if (arg1->IsSmi()) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 Handle<Object> receiver = args.receiver(); | 771 Handle<Object> receiver = args.receiver(); |
772 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 772 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
773 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); | 773 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); |
774 Handle<FixedArrayBase> elms_obj; | 774 Handle<FixedArrayBase> elms_obj; |
775 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 775 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
776 !IsJSArrayFastElementMovingAllowed(heap, | 776 !IsJSArrayFastElementMovingAllowed(heap, |
777 *Handle<JSArray>::cast(receiver))) { | 777 *Handle<JSArray>::cast(receiver))) { |
778 return CallJsBuiltin(isolate, "ArraySplice", args); | 778 return CallJsBuiltin(isolate, "ArraySplice", args); |
779 } | 779 } |
780 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 780 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
781 ASSERT(!array->map()->is_observed()); | 781 DCHECK(!array->map()->is_observed()); |
782 | 782 |
783 int len = Smi::cast(array->length())->value(); | 783 int len = Smi::cast(array->length())->value(); |
784 | 784 |
785 int n_arguments = args.length() - 1; | 785 int n_arguments = args.length() - 1; |
786 | 786 |
787 int relative_start = 0; | 787 int relative_start = 0; |
788 if (n_arguments > 0) { | 788 if (n_arguments > 0) { |
789 DisallowHeapAllocation no_gc; | 789 DisallowHeapAllocation no_gc; |
790 Object* arg1 = args[1]; | 790 Object* arg1 = args[1]; |
791 if (arg1->IsSmi()) { | 791 if (arg1->IsSmi()) { |
(...skipping 13 matching lines...) Expand all Loading... |
805 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 805 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
806 : Min(relative_start, len); | 806 : Min(relative_start, len); |
807 | 807 |
808 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is | 808 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is |
809 // given as a request to delete all the elements from the start. | 809 // given as a request to delete all the elements from the start. |
810 // And it differs from the case of undefined delete count. | 810 // And it differs from the case of undefined delete count. |
811 // This does not follow ECMA-262, but we do the same for | 811 // This does not follow ECMA-262, but we do the same for |
812 // compatibility. | 812 // compatibility. |
813 int actual_delete_count; | 813 int actual_delete_count; |
814 if (n_arguments == 1) { | 814 if (n_arguments == 1) { |
815 ASSERT(len - actual_start >= 0); | 815 DCHECK(len - actual_start >= 0); |
816 actual_delete_count = len - actual_start; | 816 actual_delete_count = len - actual_start; |
817 } else { | 817 } else { |
818 int value = 0; // ToInteger(undefined) == 0 | 818 int value = 0; // ToInteger(undefined) == 0 |
819 if (n_arguments > 1) { | 819 if (n_arguments > 1) { |
820 DisallowHeapAllocation no_gc; | 820 DisallowHeapAllocation no_gc; |
821 Object* arg2 = args[2]; | 821 Object* arg2 = args[2]; |
822 if (arg2->IsSmi()) { | 822 if (arg2->IsSmi()) { |
823 value = Smi::cast(arg2)->value(); | 823 value = Smi::cast(arg2)->value(); |
824 } else { | 824 } else { |
825 AllowHeapAllocation allow_allocation; | 825 AllowHeapAllocation allow_allocation; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 heap->MoveElements(*elms, actual_start + item_count, | 912 heap->MoveElements(*elms, actual_start + item_count, |
913 actual_start + actual_delete_count, | 913 actual_start + actual_delete_count, |
914 (len - actual_delete_count - actual_start)); | 914 (len - actual_delete_count - actual_start)); |
915 elms->FillWithHoles(new_length, len); | 915 elms->FillWithHoles(new_length, len); |
916 } | 916 } |
917 } | 917 } |
918 } else if (item_count > actual_delete_count) { | 918 } else if (item_count > actual_delete_count) { |
919 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 919 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
920 // Currently fixed arrays cannot grow too big, so | 920 // Currently fixed arrays cannot grow too big, so |
921 // we should never hit this case. | 921 // we should never hit this case. |
922 ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); | 922 DCHECK((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); |
923 | 923 |
924 // Check if array need to grow. | 924 // Check if array need to grow. |
925 if (new_length > elms->length()) { | 925 if (new_length > elms->length()) { |
926 // New backing storage is needed. | 926 // New backing storage is needed. |
927 int capacity = new_length + (new_length >> 1) + 16; | 927 int capacity = new_length + (new_length >> 1) + 16; |
928 Handle<FixedArray> new_elms = | 928 Handle<FixedArray> new_elms = |
929 isolate->factory()->NewUninitializedFixedArray(capacity); | 929 isolate->factory()->NewUninitializedFixedArray(capacity); |
930 | 930 |
931 DisallowHeapAllocation no_gc; | 931 DisallowHeapAllocation no_gc; |
932 | 932 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 AllowHeapAllocation allow_allocation; | 1010 AllowHeapAllocation allow_allocation; |
1011 return CallJsBuiltin(isolate, "ArrayConcatJS", args); | 1011 return CallJsBuiltin(isolate, "ArrayConcatJS", args); |
1012 } | 1012 } |
1013 int len = Smi::cast(JSArray::cast(arg)->length())->value(); | 1013 int len = Smi::cast(JSArray::cast(arg)->length())->value(); |
1014 | 1014 |
1015 // We shouldn't overflow when adding another len. | 1015 // We shouldn't overflow when adding another len. |
1016 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); | 1016 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); |
1017 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); | 1017 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); |
1018 USE(kHalfOfMaxInt); | 1018 USE(kHalfOfMaxInt); |
1019 result_len += len; | 1019 result_len += len; |
1020 ASSERT(result_len >= 0); | 1020 DCHECK(result_len >= 0); |
1021 | 1021 |
1022 if (result_len > FixedDoubleArray::kMaxLength) { | 1022 if (result_len > FixedDoubleArray::kMaxLength) { |
1023 AllowHeapAllocation allow_allocation; | 1023 AllowHeapAllocation allow_allocation; |
1024 return CallJsBuiltin(isolate, "ArrayConcatJS", args); | 1024 return CallJsBuiltin(isolate, "ArrayConcatJS", args); |
1025 } | 1025 } |
1026 | 1026 |
1027 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); | 1027 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); |
1028 has_double = has_double || IsFastDoubleElementsKind(arg_kind); | 1028 has_double = has_double || IsFastDoubleElementsKind(arg_kind); |
1029 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); | 1029 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); |
1030 if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { | 1030 if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { |
(...skipping 24 matching lines...) Expand all Loading... |
1055 // performance degradation. Revisit this later. | 1055 // performance degradation. Revisit this later. |
1056 JSArray* array = JSArray::cast(args[i]); | 1056 JSArray* array = JSArray::cast(args[i]); |
1057 int len = Smi::cast(array->length())->value(); | 1057 int len = Smi::cast(array->length())->value(); |
1058 ElementsKind from_kind = array->GetElementsKind(); | 1058 ElementsKind from_kind = array->GetElementsKind(); |
1059 if (len > 0) { | 1059 if (len > 0) { |
1060 accessor->CopyElements(array, 0, from_kind, storage, j, len); | 1060 accessor->CopyElements(array, 0, from_kind, storage, j, len); |
1061 j += len; | 1061 j += len; |
1062 } | 1062 } |
1063 } | 1063 } |
1064 | 1064 |
1065 ASSERT(j == result_len); | 1065 DCHECK(j == result_len); |
1066 | 1066 |
1067 return *result_array; | 1067 return *result_array; |
1068 } | 1068 } |
1069 | 1069 |
1070 | 1070 |
1071 // ----------------------------------------------------------------------------- | 1071 // ----------------------------------------------------------------------------- |
1072 // Generator and strict mode poison pills | 1072 // Generator and strict mode poison pills |
1073 | 1073 |
1074 | 1074 |
1075 BUILTIN(StrictModePoisonPill) { | 1075 BUILTIN(StrictModePoisonPill) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 if (current == heap->null_value()) current = heap->undefined_value(); | 1145 if (current == heap->null_value()) current = heap->undefined_value(); |
1146 *arg = current; | 1146 *arg = current; |
1147 } | 1147 } |
1148 return holder; | 1148 return holder; |
1149 } | 1149 } |
1150 | 1150 |
1151 | 1151 |
1152 template <bool is_construct> | 1152 template <bool is_construct> |
1153 MUST_USE_RESULT static Object* HandleApiCallHelper( | 1153 MUST_USE_RESULT static Object* HandleApiCallHelper( |
1154 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { | 1154 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { |
1155 ASSERT(is_construct == CalledAsConstructor(isolate)); | 1155 DCHECK(is_construct == CalledAsConstructor(isolate)); |
1156 Heap* heap = isolate->heap(); | 1156 Heap* heap = isolate->heap(); |
1157 | 1157 |
1158 HandleScope scope(isolate); | 1158 HandleScope scope(isolate); |
1159 Handle<JSFunction> function = args.called_function(); | 1159 Handle<JSFunction> function = args.called_function(); |
1160 ASSERT(function->shared()->IsApiFunction()); | 1160 DCHECK(function->shared()->IsApiFunction()); |
1161 | 1161 |
1162 Handle<FunctionTemplateInfo> fun_data( | 1162 Handle<FunctionTemplateInfo> fun_data( |
1163 function->shared()->get_api_func_data(), isolate); | 1163 function->shared()->get_api_func_data(), isolate); |
1164 if (is_construct) { | 1164 if (is_construct) { |
1165 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1165 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1166 isolate, fun_data, | 1166 isolate, fun_data, |
1167 isolate->factory()->ConfigureInstance( | 1167 isolate->factory()->ConfigureInstance( |
1168 fun_data, Handle<JSObject>::cast(args.receiver()))); | 1168 fun_data, Handle<JSObject>::cast(args.receiver()))); |
1169 } | 1169 } |
1170 | 1170 |
1171 SharedFunctionInfo* shared = function->shared(); | 1171 SharedFunctionInfo* shared = function->shared(); |
1172 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 1172 if (shared->strict_mode() == SLOPPY && !shared->native()) { |
1173 Object* recv = args[0]; | 1173 Object* recv = args[0]; |
1174 ASSERT(!recv->IsNull()); | 1174 DCHECK(!recv->IsNull()); |
1175 if (recv->IsUndefined()) args[0] = function->global_proxy(); | 1175 if (recv->IsUndefined()) args[0] = function->global_proxy(); |
1176 } | 1176 } |
1177 | 1177 |
1178 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); | 1178 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); |
1179 | 1179 |
1180 if (raw_holder->IsNull()) { | 1180 if (raw_holder->IsNull()) { |
1181 // This function cannot be called with the given receiver. Abort! | 1181 // This function cannot be called with the given receiver. Abort! |
1182 Handle<Object> obj = | 1182 Handle<Object> obj = |
1183 isolate->factory()->NewTypeError( | 1183 isolate->factory()->NewTypeError( |
1184 "illegal_invocation", HandleVector(&function, 1)); | 1184 "illegal_invocation", HandleVector(&function, 1)); |
1185 return isolate->Throw(*obj); | 1185 return isolate->Throw(*obj); |
1186 } | 1186 } |
1187 | 1187 |
1188 Object* raw_call_data = fun_data->call_code(); | 1188 Object* raw_call_data = fun_data->call_code(); |
1189 if (!raw_call_data->IsUndefined()) { | 1189 if (!raw_call_data->IsUndefined()) { |
1190 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1190 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
1191 Object* callback_obj = call_data->callback(); | 1191 Object* callback_obj = call_data->callback(); |
1192 v8::FunctionCallback callback = | 1192 v8::FunctionCallback callback = |
1193 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1193 v8::ToCData<v8::FunctionCallback>(callback_obj); |
1194 Object* data_obj = call_data->data(); | 1194 Object* data_obj = call_data->data(); |
1195 Object* result; | 1195 Object* result; |
1196 | 1196 |
1197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 1197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
1198 ASSERT(raw_holder->IsJSObject()); | 1198 DCHECK(raw_holder->IsJSObject()); |
1199 | 1199 |
1200 FunctionCallbackArguments custom(isolate, | 1200 FunctionCallbackArguments custom(isolate, |
1201 data_obj, | 1201 data_obj, |
1202 *function, | 1202 *function, |
1203 raw_holder, | 1203 raw_holder, |
1204 &args[0] - 1, | 1204 &args[0] - 1, |
1205 args.length() - 1, | 1205 args.length() - 1, |
1206 is_construct); | 1206 is_construct); |
1207 | 1207 |
1208 v8::Handle<v8::Value> value = custom.Call(callback); | 1208 v8::Handle<v8::Value> value = custom.Call(callback); |
(...skipping 24 matching lines...) Expand all Loading... |
1233 | 1233 |
1234 // Helper function to handle calls to non-function objects created through the | 1234 // Helper function to handle calls to non-function objects created through the |
1235 // API. The object can be called as either a constructor (using new) or just as | 1235 // API. The object can be called as either a constructor (using new) or just as |
1236 // a function (without new). | 1236 // a function (without new). |
1237 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( | 1237 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
1238 Isolate* isolate, | 1238 Isolate* isolate, |
1239 bool is_construct_call, | 1239 bool is_construct_call, |
1240 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { | 1240 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { |
1241 // Non-functions are never called as constructors. Even if this is an object | 1241 // Non-functions are never called as constructors. Even if this is an object |
1242 // called as a constructor the delegate call is not a construct call. | 1242 // called as a constructor the delegate call is not a construct call. |
1243 ASSERT(!CalledAsConstructor(isolate)); | 1243 DCHECK(!CalledAsConstructor(isolate)); |
1244 Heap* heap = isolate->heap(); | 1244 Heap* heap = isolate->heap(); |
1245 | 1245 |
1246 Handle<Object> receiver = args.receiver(); | 1246 Handle<Object> receiver = args.receiver(); |
1247 | 1247 |
1248 // Get the object called. | 1248 // Get the object called. |
1249 JSObject* obj = JSObject::cast(*receiver); | 1249 JSObject* obj = JSObject::cast(*receiver); |
1250 | 1250 |
1251 // Get the invocation callback from the function descriptor that was | 1251 // Get the invocation callback from the function descriptor that was |
1252 // used to create the called object. | 1252 // used to create the called object. |
1253 ASSERT(obj->map()->has_instance_call_handler()); | 1253 DCHECK(obj->map()->has_instance_call_handler()); |
1254 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); | 1254 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); |
1255 ASSERT(constructor->shared()->IsApiFunction()); | 1255 DCHECK(constructor->shared()->IsApiFunction()); |
1256 Object* handler = | 1256 Object* handler = |
1257 constructor->shared()->get_api_func_data()->instance_call_handler(); | 1257 constructor->shared()->get_api_func_data()->instance_call_handler(); |
1258 ASSERT(!handler->IsUndefined()); | 1258 DCHECK(!handler->IsUndefined()); |
1259 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); | 1259 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); |
1260 Object* callback_obj = call_data->callback(); | 1260 Object* callback_obj = call_data->callback(); |
1261 v8::FunctionCallback callback = | 1261 v8::FunctionCallback callback = |
1262 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1262 v8::ToCData<v8::FunctionCallback>(callback_obj); |
1263 | 1263 |
1264 // Get the data for the call and perform the callback. | 1264 // Get the data for the call and perform the callback. |
1265 Object* result; | 1265 Object* result; |
1266 { | 1266 { |
1267 HandleScope scope(isolate); | 1267 HandleScope scope(isolate); |
1268 LOG(isolate, ApiObjectAccess("call non-function", obj)); | 1268 LOG(isolate, ApiObjectAccess("call non-function", obj)); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) | 1594 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) |
1595 BUILTIN_LIST_H(DEF_FUNCTION_PTR_H) | 1595 BUILTIN_LIST_H(DEF_FUNCTION_PTR_H) |
1596 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) | 1596 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) |
1597 | 1597 |
1598 #undef DEF_FUNCTION_PTR_C | 1598 #undef DEF_FUNCTION_PTR_C |
1599 #undef DEF_FUNCTION_PTR_A | 1599 #undef DEF_FUNCTION_PTR_A |
1600 } | 1600 } |
1601 | 1601 |
1602 | 1602 |
1603 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { | 1603 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { |
1604 ASSERT(!initialized_); | 1604 DCHECK(!initialized_); |
1605 | 1605 |
1606 // Create a scope for the handles in the builtins. | 1606 // Create a scope for the handles in the builtins. |
1607 HandleScope scope(isolate); | 1607 HandleScope scope(isolate); |
1608 | 1608 |
1609 const BuiltinDesc* functions = builtin_function_table.functions(); | 1609 const BuiltinDesc* functions = builtin_function_table.functions(); |
1610 | 1610 |
1611 // For now we generate builtin adaptor code into a stack-allocated | 1611 // For now we generate builtin adaptor code into a stack-allocated |
1612 // buffer, before copying it into individual code objects. Be careful | 1612 // buffer, before copying it into individual code objects. Be careful |
1613 // with alignment, some platforms don't like unaligned code. | 1613 // with alignment, some platforms don't like unaligned code. |
1614 #ifdef DEBUG | 1614 #ifdef DEBUG |
1615 // We can generate a lot of debug code on Arm64. | 1615 // We can generate a lot of debug code on Arm64. |
1616 const size_t buffer_size = 32*KB; | 1616 const size_t buffer_size = 32*KB; |
1617 #else | 1617 #else |
1618 const size_t buffer_size = 8*KB; | 1618 const size_t buffer_size = 8*KB; |
1619 #endif | 1619 #endif |
1620 union { int force_alignment; byte buffer[buffer_size]; } u; | 1620 union { int force_alignment; byte buffer[buffer_size]; } u; |
1621 | 1621 |
1622 // Traverse the list of builtins and generate an adaptor in a | 1622 // Traverse the list of builtins and generate an adaptor in a |
1623 // separate code object for each one. | 1623 // separate code object for each one. |
1624 for (int i = 0; i < builtin_count; i++) { | 1624 for (int i = 0; i < builtin_count; i++) { |
1625 if (create_heap_objects) { | 1625 if (create_heap_objects) { |
1626 MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); | 1626 MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); |
1627 // Generate the code/adaptor. | 1627 // Generate the code/adaptor. |
1628 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); | 1628 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); |
1629 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); | 1629 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
1630 // We pass all arguments to the generator, but it may not use all of | 1630 // We pass all arguments to the generator, but it may not use all of |
1631 // them. This works because the first arguments are on top of the | 1631 // them. This works because the first arguments are on top of the |
1632 // stack. | 1632 // stack. |
1633 ASSERT(!masm.has_frame()); | 1633 DCHECK(!masm.has_frame()); |
1634 g(&masm, functions[i].name, functions[i].extra_args); | 1634 g(&masm, functions[i].name, functions[i].extra_args); |
1635 // Move the code into the object heap. | 1635 // Move the code into the object heap. |
1636 CodeDesc desc; | 1636 CodeDesc desc; |
1637 masm.GetCode(&desc); | 1637 masm.GetCode(&desc); |
1638 Code::Flags flags = functions[i].flags; | 1638 Code::Flags flags = functions[i].flags; |
1639 Handle<Code> code = | 1639 Handle<Code> code = |
1640 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); | 1640 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
1641 // Log the event and add the code to the builtins array. | 1641 // Log the event and add the code to the builtins array. |
1642 PROFILE(isolate, | 1642 PROFILE(isolate, |
1643 CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name)); | 1643 CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name)); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 } | 1718 } |
1719 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1719 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1720 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1720 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1721 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1721 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1722 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1722 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1723 #undef DEFINE_BUILTIN_ACCESSOR_C | 1723 #undef DEFINE_BUILTIN_ACCESSOR_C |
1724 #undef DEFINE_BUILTIN_ACCESSOR_A | 1724 #undef DEFINE_BUILTIN_ACCESSOR_A |
1725 | 1725 |
1726 | 1726 |
1727 } } // namespace v8::internal | 1727 } } // namespace v8::internal |
OLD | NEW |