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

Side by Side Diff: src/ic/mips/ic-mips.cc

Issue 1189153002: Revert of [strong] Implement strong mode restrictions on property access (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « src/ic/mips/handler-compiler-mips.cc ('k') | src/ic/mips64/handler-compiler-mips64.cc » ('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 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 5
6 #include "src/v8.h" 6 #include "src/v8.h"
7 7
8 #if V8_TARGET_ARCH_MIPS 8 #if V8_TARGET_ARCH_MIPS
9 9
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); 156 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE);
157 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 157 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
158 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); 158 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE));
159 } 159 }
160 160
161 161
162 // Loads an indexed element from a fast case array. 162 // Loads an indexed element from a fast case array.
163 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 163 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
164 Register key, Register elements, 164 Register key, Register elements,
165 Register scratch1, Register scratch2, 165 Register scratch1, Register scratch2,
166 Register result, Label* slow, 166 Register result, Label* slow) {
167 LanguageMode language_mode) {
168 // Register use: 167 // Register use:
169 // 168 //
170 // receiver - holds the receiver on entry. 169 // receiver - holds the receiver on entry.
171 // Unchanged unless 'result' is the same register. 170 // Unchanged unless 'result' is the same register.
172 // 171 //
173 // key - holds the smi key on entry. 172 // key - holds the smi key on entry.
174 // Unchanged unless 'result' is the same register. 173 // Unchanged unless 'result' is the same register.
175 // 174 //
176 // result - holds the result on exit if the load succeeded. 175 // result - holds the result on exit if the load succeeded.
177 // Allowed to be the the same as 'receiver' or 'key'. 176 // Allowed to be the the same as 'receiver' or 'key'.
178 // Unchanged on bailout so 'receiver' and 'key' can be safely 177 // Unchanged on bailout so 'receiver' and 'key' can be safely
179 // used by further computation. 178 // used by further computation.
180 // 179 //
181 // Scratch registers: 180 // Scratch registers:
182 // 181 //
183 // elements - holds the elements of the receiver and its prototypes. 182 // elements - holds the elements of the receiver and its prototypes.
184 // 183 //
185 // scratch1 - used to hold elements length, bit fields, base addresses. 184 // scratch1 - used to hold elements length, bit fields, base addresses.
186 // 185 //
187 // scratch2 - used to hold maps, prototypes, and the loaded value. 186 // scratch2 - used to hold maps, prototypes, and the loaded value.
188 Label check_prototypes, check_next_prototype; 187 Label check_prototypes, check_next_prototype;
189 Label done, in_bounds, absent; 188 Label done, in_bounds, return_undefined;
190 189
191 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 190 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
192 __ AssertFastElements(elements); 191 __ AssertFastElements(elements);
193 192
194 // Check that the key (index) is within bounds. 193 // Check that the key (index) is within bounds.
195 __ lw(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 194 __ lw(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
196 __ Branch(&in_bounds, lo, key, Operand(scratch1)); 195 __ Branch(&in_bounds, lo, key, Operand(scratch1));
197 // Out-of-bounds. Check the prototype chain to see if we can just return 196 // Out-of-bounds. Check the prototype chain to see if we can just return
198 // 'undefined'. 197 // 'undefined'.
199 // Negative keys can't take the fast OOB path. 198 // Negative keys can't take the fast OOB path.
200 __ Branch(slow, lt, key, Operand(zero_reg)); 199 __ Branch(slow, lt, key, Operand(zero_reg));
201 __ bind(&check_prototypes); 200 __ bind(&check_prototypes);
202 __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 201 __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
203 __ bind(&check_next_prototype); 202 __ bind(&check_next_prototype);
204 __ lw(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset)); 203 __ lw(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
205 // scratch2: current prototype 204 // scratch2: current prototype
206 __ LoadRoot(at, Heap::kNullValueRootIndex); 205 __ LoadRoot(at, Heap::kNullValueRootIndex);
207 __ Branch(&absent, eq, scratch2, Operand(at)); 206 __ Branch(&return_undefined, eq, scratch2, Operand(at));
208 __ lw(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset)); 207 __ lw(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
209 __ lw(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 208 __ lw(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
210 // elements: elements of current prototype 209 // elements: elements of current prototype
211 // scratch2: map of current prototype 210 // scratch2: map of current prototype
212 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); 211 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kInstanceTypeOffset));
213 __ Branch(slow, lo, scratch1, Operand(JS_OBJECT_TYPE)); 212 __ Branch(slow, lo, scratch1, Operand(JS_OBJECT_TYPE));
214 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset)); 213 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
215 __ And(at, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | 214 __ And(at, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
216 (1 << Map::kHasIndexedInterceptor))); 215 (1 << Map::kHasIndexedInterceptor)));
217 __ Branch(slow, ne, at, Operand(zero_reg)); 216 __ Branch(slow, ne, at, Operand(zero_reg));
218 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); 217 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
219 __ Branch(slow, ne, elements, Operand(at)); 218 __ Branch(slow, ne, elements, Operand(at));
220 __ Branch(&check_next_prototype); 219 __ Branch(&check_next_prototype);
221 220
222 __ bind(&absent); 221 __ bind(&return_undefined);
223 if (is_strong(language_mode)) { 222 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
224 // Strong mode accesses must throw in this case, so call the runtime. 223 __ Branch(&done);
225 __ Branch(slow);
226 } else {
227 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
228 __ Branch(&done);
229 }
230 224
231 __ bind(&in_bounds); 225 __ bind(&in_bounds);
232 // Fast case: Do the load. 226 // Fast case: Do the load.
233 __ Addu(scratch1, elements, 227 __ Addu(scratch1, elements,
234 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 228 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
235 // The key is a smi. 229 // The key is a smi.
236 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 230 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
237 __ sll(at, key, kPointerSizeLog2 - kSmiTagSize); 231 __ sll(at, key, kPointerSizeLog2 - kSmiTagSize);
238 __ addu(at, at, scratch1); 232 __ addu(at, at, scratch1);
239 __ lw(scratch2, MemOperand(at)); 233 __ lw(scratch2, MemOperand(at));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 Label slow; 278 Label slow;
285 279
286 __ lw(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), 280 __ lw(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
287 JSObject::kPropertiesOffset)); 281 JSObject::kPropertiesOffset));
288 GenerateDictionaryLoad(masm, &slow, dictionary, 282 GenerateDictionaryLoad(masm, &slow, dictionary,
289 LoadDescriptor::NameRegister(), v0, a3, t0); 283 LoadDescriptor::NameRegister(), v0, a3, t0);
290 __ Ret(); 284 __ Ret();
291 285
292 // Dictionary load failed, go slow (but don't miss). 286 // Dictionary load failed, go slow (but don't miss).
293 __ bind(&slow); 287 __ bind(&slow);
294 GenerateSlow(masm); 288 GenerateRuntimeGetProperty(masm);
295 } 289 }
296 290
297 291
298 // A register that isn't one of the parameters to the load ic. 292 // A register that isn't one of the parameters to the load ic.
299 static const Register LoadIC_TempRegister() { return a3; } 293 static const Register LoadIC_TempRegister() { return a3; }
300 294
301 295
302 static void LoadIC_PushArgs(MacroAssembler* masm) { 296 static void LoadIC_PushArgs(MacroAssembler* masm) {
303 Register receiver = LoadDescriptor::ReceiverRegister(); 297 Register receiver = LoadDescriptor::ReceiverRegister();
304 Register name = LoadDescriptor::NameRegister(); 298 Register name = LoadDescriptor::NameRegister();
(...skipping 14 matching lines...) Expand all
319 313
320 LoadIC_PushArgs(masm); 314 LoadIC_PushArgs(masm);
321 315
322 // Perform tail call to the entry. 316 // Perform tail call to the entry.
323 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 317 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
324 int arg_count = 4; 318 int arg_count = 4;
325 __ TailCallExternalReference(ref, arg_count, 1); 319 __ TailCallExternalReference(ref, arg_count, 1);
326 } 320 }
327 321
328 322
329 void LoadIC::GenerateSlow(MacroAssembler* masm) { 323 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
330 // The return address is in ra. 324 // The return address is in ra.
331 325
332 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 326 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
333 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); 327 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
334 328
335 ExternalReference ref = 329 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
336 ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
337 int arg_count = 2;
338 __ TailCallExternalReference(ref, arg_count, 1);
339 } 330 }
340 331
341 332
342 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 333 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
343 // The return address is in ra. 334 // The return address is in ra.
344 Isolate* isolate = masm->isolate(); 335 Isolate* isolate = masm->isolate();
345 336
346 DCHECK(!AreAliased(t0, t1, LoadWithVectorDescriptor::SlotRegister(), 337 DCHECK(!AreAliased(t0, t1, LoadWithVectorDescriptor::SlotRegister(),
347 LoadWithVectorDescriptor::VectorRegister())); 338 LoadWithVectorDescriptor::VectorRegister()));
348 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1); 339 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1);
349 340
350 LoadIC_PushArgs(masm); 341 LoadIC_PushArgs(masm);
351 342
352 // Perform tail call to the entry. 343 // Perform tail call to the entry.
353 ExternalReference ref = 344 ExternalReference ref =
354 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 345 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
355 346
356 int arg_count = 4; 347 int arg_count = 4;
357 __ TailCallExternalReference(ref, arg_count, 1); 348 __ TailCallExternalReference(ref, arg_count, 1);
358 } 349 }
359 350
360 351
361 void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) { 352 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
362 // The return address is in ra. 353 // The return address is in ra.
363 354
364 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 355 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
365 356
366 ExternalReference ref = 357 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
367 ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
368 int arg_count = 2;
369 __ TailCallExternalReference(ref, arg_count, 1);
370 } 358 }
371 359
372 360
373 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm, 361 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
374 LanguageMode language_mode) {
375 // The return address is in ra. 362 // The return address is in ra.
376 Label slow, check_name, index_smi, index_name, property_array_property; 363 Label slow, check_name, index_smi, index_name, property_array_property;
377 Label probe_dictionary, check_number_dictionary; 364 Label probe_dictionary, check_number_dictionary;
378 365
379 Register key = LoadDescriptor::NameRegister(); 366 Register key = LoadDescriptor::NameRegister();
380 Register receiver = LoadDescriptor::ReceiverRegister(); 367 Register receiver = LoadDescriptor::ReceiverRegister();
381 DCHECK(key.is(a2)); 368 DCHECK(key.is(a2));
382 DCHECK(receiver.is(a1)); 369 DCHECK(receiver.is(a1));
383 370
384 Isolate* isolate = masm->isolate(); 371 Isolate* isolate = masm->isolate();
385 372
386 // Check that the key is a smi. 373 // Check that the key is a smi.
387 __ JumpIfNotSmi(key, &check_name); 374 __ JumpIfNotSmi(key, &check_name);
388 __ bind(&index_smi); 375 __ bind(&index_smi);
389 // Now the key is known to be a smi. This place is also jumped to from below 376 // Now the key is known to be a smi. This place is also jumped to from below
390 // where a numeric string is converted to a smi. 377 // where a numeric string is converted to a smi.
391 378
392 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3, 379 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
393 Map::kHasIndexedInterceptor, &slow); 380 Map::kHasIndexedInterceptor, &slow);
394 381
395 // Check the receiver's map to see if it has fast elements. 382 // Check the receiver's map to see if it has fast elements.
396 __ CheckFastElements(a0, a3, &check_number_dictionary); 383 __ CheckFastElements(a0, a3, &check_number_dictionary);
397 384
398 GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow, 385 GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow);
399 language_mode);
400 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3); 386 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3);
401 __ Ret(); 387 __ Ret();
402 388
403 __ bind(&check_number_dictionary); 389 __ bind(&check_number_dictionary);
404 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 390 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
405 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset)); 391 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset));
406 392
407 // Check whether the elements is a number dictionary. 393 // Check whether the elements is a number dictionary.
408 // a3: elements map 394 // a3: elements map
409 // t0: elements 395 // t0: elements
410 __ LoadRoot(at, Heap::kHashTableMapRootIndex); 396 __ LoadRoot(at, Heap::kHashTableMapRootIndex);
411 __ Branch(&slow, ne, a3, Operand(at)); 397 __ Branch(&slow, ne, a3, Operand(at));
412 __ sra(a0, key, kSmiTagSize); 398 __ sra(a0, key, kSmiTagSize);
413 __ LoadFromNumberDictionary(&slow, t0, key, v0, a0, a3, t1); 399 __ LoadFromNumberDictionary(&slow, t0, key, v0, a0, a3, t1);
414 __ Ret(); 400 __ Ret();
415 401
416 // Slow case, key and receiver still in a2 and a1. 402 // Slow case, key and receiver still in a2 and a1.
417 __ bind(&slow); 403 __ bind(&slow);
418 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, t0, 404 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, t0,
419 a3); 405 a3);
420 GenerateSlow(masm); 406 GenerateRuntimeGetProperty(masm);
421 407
422 __ bind(&check_name); 408 __ bind(&check_name);
423 GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow); 409 GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
424 410
425 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3, 411 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
426 Map::kHasNamedInterceptor, &slow); 412 Map::kHasNamedInterceptor, &slow);
427 413
428 414
429 // If the receiver is a fast-case object, check the stub cache. Otherwise 415 // If the receiver is a fast-case object, check the stub cache. Otherwise
430 // probe the dictionary. 416 // probe the dictionary.
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 patcher.ChangeBranchCondition(ne); 867 patcher.ChangeBranchCondition(ne);
882 } else { 868 } else {
883 DCHECK(Assembler::IsBne(branch_instr)); 869 DCHECK(Assembler::IsBne(branch_instr));
884 patcher.ChangeBranchCondition(eq); 870 patcher.ChangeBranchCondition(eq);
885 } 871 }
886 } 872 }
887 } // namespace internal 873 } // namespace internal
888 } // namespace v8 874 } // namespace v8
889 875
890 #endif // V8_TARGET_ARCH_MIPS 876 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic/mips/handler-compiler-mips.cc ('k') | src/ic/mips64/handler-compiler-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698